繁体   English   中英

为什么 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)
}

Output 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)
}

Output 9

我已经使用计时器来计算执行时间,但是协程代码需要更长的时间。

为什么它会这样工作,我怎样才能让协程部分更快?

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

首先,你永远不应该相信第一次运行代码的时间。 这是所有重量级 class 初始化发生的时间,包括您通过调用库 function 间接接触的类的初始化。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM