为什么 Kotlin 协程需要更长的时间

Why Kotlin Coroutine is taking longer time

我有两个程序

  1. 与协程

我有 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

  1. 没有协程
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

我用timer计算了执行时间,但是协程代码用的时间比较长

为什么会这样,我怎样才能使协程部分更快?

您的代码忽略了很多问题,这些问题使您的两个示例非常不同。

首先,您永远不要相信第一个 运行 通过代码的时间。这是所有重量级 class 初始化发生的时间,包括您通过调用库函数间接接触的 classes 的初始化。

其次,您还忽略了 JIT 编译器对字节码所做的所有优化。在你的情况下最重要的是代码除了增加局部变量而不在之后使用它们之外什么都不做。 JIT 编译器很乐意完全删除您的循环。即使您之后使用结果,编译器也可以对 1,000,000 次增量后的结果值进行一些简单的推理。

您的第一个示例与协程有根本的不同,因为它将任务提交给 commonPool 执行程序服务。这意味着您的递增代码发生在捕获局部变量的 lambda 中。为了使其工作,编译器必须将其转换为附加到 lambda 的实例变量。就编译器而言,这混淆了水域,证明可以安全地消除循环。

然而,即使您考虑了所有这些事情,您的代码也以基本方式被破坏:您不等待启动的协程完成。因此,在您解决上述问题并让循环执行一些您实际检查其结果的重要工作后,您会发现协程示例报告不依赖于循环迭代次数的恒定时间。

我认为最能解释您当前结果的是初始化成本。只需在整个代码上放置一个大的外部循环,协程示例的性能就会比现在好得多。