并行运行单声道似乎不会更快 [英] Run mono in parallel doesn't seems faster
问题描述
所以我尝试并行地发出API请求,但似乎并不快。我做错了吗?以下是我的代码。
fun getUserInfo(username: String): Mono<String> {
return webclient
// some config and params
.post()
.bodyToMono(String::class)
.subscribeOn(Schedulers.parallel())
}
fun main(){
val time = measureTimeMillis {
Mono.zip(getUserInfo("doge"), getUserInfo("cheems"), etc...)
.map { user ->listOf(it.t1, it.t2, etc...) }
.block()
}
// give the same amount of time doesn't seems faster
// with and without subscribeOn(Schedulers.parallel())
}
推荐答案
它与您的代码无关。
您必须了解,任何I/O工作都是在等待中度过的。就像在等待回复一样。
如果我们查看一个线程的生命周期,它将执行一些预处理,然后发送请求。当请求被发送时,它必须等待响应。这是花费大部分时间的地方,然后您将获得响应并处理该响应。事情是这样的,多达90%的请求时间可以用于等待。让线程等待会浪费大量资源。
这就是网络通量/反应堆的优点。当发送请求时,线程不会等待,它将继续处理其他请求/响应,当第一个请求响应返回时,任何空闲线程都可以选择该响应,它不必是最初发送请求的线程。
我刚才描述的通常是所谓的异步工作。
让我们看看你在做什么。您希望并行运行您的请求,即同时在多个核心上利用多个线程。
为此,您需要联系其他CPU,并告诉它们为即将到来的工作做好准备。然后,CPU需要在每个CPU上初始化多个线程,然后必须将数据发送到所有CPU。如您所见,这里涉及设置时间。
那么所有的请求都是同时从多个CPU发出的,但是等待响应的时间是恒定的!它的等待时间与以前完全相同(高达总请求时间的90%)。然后,当所有响应返回时,它们被收集并在多个CPU上处理,然后被发送回原始CPU上的原始线程。
你得到了什么?很可能几乎什么都没有,但您也很可能使用了更多的资源来实现这一非常、非常小的收益。
如果您需要原始的CPU计算能力,如某种类型的计算,例如3D渲染器,或者我不知道,破解哈希等,而不是I/O工作,并行通常是好的。
I/O工作通常更多地与编排有关,而不是原始的CPU能力。慢响应不会通过并行计算来解决,慢响应总是慢响应。您只会消耗更多的资源而没有好处。这就是常规flatMap
在反应堆中如此强大的原因。
它将为您异步执行所有工作,而无需处理线程、锁定、同步、联接等。它将使用尽可能少的资源以尽可能快的速度执行所有工作。
这篇关于并行运行单声道似乎不会更快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!