我有两个节目
我有3个循环,我尝试将每个循环分配给一个协同线,以便快速执行。
import kotlinx.coroutines.*
fun main() {
val time = measureTimeMillis() {
var i=0
var j=0
var k=0
GlobalScope.launch(Dispatchers.Default){
while(i<1000000)
i++ }
GlobalScope.launch(Dispatchers.Default){
while(j<1000000)
j++}
GlobalScope.launch(Dispatchers.Default){
while(k<1000000)
k++}
}
println(time)
}输出109
无Coroutine
import kotlin.system.measureTimeMillis
import kotlinx.coroutines.*
fun main() {
val time = measureTimeMillis() {
var i=0
var j=0
var k=0
while(i<1000000)
i++
while(j<1000000)
j++
while(k<1000000)
k++
}
println(time)
}输出9
我使用计时器来计算执行时间,但是协同线代码花费的时间更长。
为什么它是这样工作的,我如何使协同线部分更快?
发布于 2021-03-12 10:44:47
您的代码忽略了许多使您的两个示例非常不同的问题。
首先,您不应该相信第一次运行代码的时间。这时发生了所有重量级类初始化,包括通过调用库函数间接接触的类的初始化。
其次,您还忽略了JIT编译器对字节码所做的所有优化。在您的情况下,最重要的是代码只会增加局部变量,而不会在以后使用它们。JIT编译器将乐于完全删除您的循环。即使之后使用结果,编译器也可能能够对结果值在1,000,000次增量后的结果进行一些简单的推理。
使用协同机制的第一个示例从根本上说是不同的,因为它将任务提交给commonPool执行器服务。这意味着增量代码发生在捕获局部变量的lambda中。为了使其工作,编译器必须将其转换为附加到lambda的实例变量。这在编译器证明循环可以安全消除方面混水摸鱼。
然而,即使您考虑了所有这些事情,您的代码也是以一种基本的方式被破坏的:您不需要等待启动协同机制的完成。因此,在修复了上面的问题并使循环做了一些非常重要的工作之后,您就会发现coroutine示例报告了不依赖于循环迭代次数的常数时间。
我认为最好的解释是您当前的结果是初始化成本。只需在整个代码上加上一个很大的外部循环,coroutine示例的性能就会比现在好得多。
https://stackoverflow.com/questions/66595600
复制相似问题