Время выполнения реактивного программирования - PullRequest
0 голосов
/ 06 июля 2018

Это идеальный способ найти время выполнения метода (getFavouriteDetails()) в реактивном программировании?

public List<Favourites> getFavouriteDetails(String userId){
    userService.getFavorites(userId) 
               .flatMap(favoriteService::getDetails) 
               .switchIfEmpty(suggestionService.getSuggestions()) 
               .take(5) 
               .publishOn(UiUtils.uiThreadScheduler()) 
               .subscribe(uiList::show, UiUtils::errorPopup)
               .flatMap(a -> Mono.subscriberContext().map(ctx -> {
                         log.info("Time taken : " + Duration.between(ctx.get(key), Instant.now()).toMillis() + " milliseconds.");
                         return a;
                     }))
               .subscriberContext(ctx -> ctx.put(key, Instant.now()))
}

1 Ответ

0 голосов
/ 09 июля 2018

Для определения времени метода самый простой способ в Java - это использование long System.nanoTime(). Instant и System.currentTimeMillis предназначены для операций с настенными часами и не гарантируют, что они будут однообразными или достаточно точными ...

В Reactor, чтобы измерить время, необходимое для завершения последовательности, вам обычно нужно начинать синхронизацию по подписке (ничего не происходит, пока вы не подписались) и останавливать синхронизацию в пределах doFinally (который выполняет некоторый код на стороне основной последовательности всякий раз, когда она завершается, ошибается или отменяется).

Здесь вы, однако, подписываетесь самостоятельно, поэтому нет риска, что вы будете иметь несколько подписок. Таким образом, вы можете покончить с ограничением «время начала подписки».

Это дает нам что-то вроде этого:

public List<Favourites> getFavouriteDetails(String userId){
    final long start = System.nanoTime();
    userService.getFavorites(userId) 
               .flatMap(favoriteService::getDetails) 
               .switchIfEmpty(suggestionService.getSuggestions()) 
               .take(5) 
               .publishOn(UiUtils.uiThreadScheduler())
               .doFinally(endType -> log.info("Time taken : " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " milliseconds."))
               .subscribe(uiList::show, UiUtils::errorPopup);
    //return needed!
}

Обратите внимание, что есть также оператор elapsed(), который измеряет время между подпиской и первым onNext, а затем между последующими onNexts. Он выводит Flux<Tuple2<Long, T>>, и вы можете агрегировать длинные, чтобы получить общее время, но в этом случае вы потеряете природу T s в реальном времени.

...