[英]Execution time reactive programming
這是在反應式編程中找到方法( 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()))
}
兩種方法可確保您僅在訂閱時測量執行時間 -
flatMapMany
將 Mono 包裹在 Flux flatMapMany
。 這也返回一個 Flux 。onSubscribe
和日志經過時間的doFinally
。示例代碼 -
timeFluxV1(getFavouriteDetails(userId)).subscribe(uiList::show, UiUtils::errorPopup);
timeFluxV1(getFavouriteDetails(userId)).subscribe(uiList::show, UiUtils::errorPopup);
private <T> Flux<T> timeFluxV1(Flux<T> flux) {
return Mono.fromSupplier(System::nanoTime)
.flatMapMany(time -> flux.doFinally(sig -> log.info("Time taken : " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - time) + " milliseconds.")));
}
private <T> Flux<T> timeFluxV2(Flux<T> flux) {
AtomicReference<Long> startTime = new AtomicReference<>();
return flux.doOnSubscribe(x -> startTime.set(System.nanoTime()))
.doFinally(x -> log.info("Time taken : " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime.get()) + " milliseconds."));
}
public Flux<Favourites> getFavouriteDetails(String userId) {
return userService.getFavorites(userId)
.flatMap(favoriteService::getDetails)
.switchIfEmpty(suggestionService.getSuggestions())
.take(5)
.publishOn(UiUtils.uiThreadScheduler());
}
要對方法計時,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>>
,你可以聚合 longs 以獲得整體時間,但在這種情況下你會失去T
s的“實時”性質。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.