首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么科林·科鲁丁要花更长的时间

为什么科林·科鲁丁要花更长的时间
EN

Stack Overflow用户
提问于 2021-03-12 07:02:18
回答 1查看 217关注 0票数 1

我有两个节目

  1. 与协同素

我有3个循环,我尝试将每个循环分配给一个协同线,以便快速执行。

代码语言:javascript
复制
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

代码语言:javascript
复制
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

我使用计时器来计算执行时间,但是协同线代码花费的时间更长。

为什么它是这样工作的,我如何使协同线部分更快?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-12 10:44:47

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

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

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

使用协同机制的第一个示例从根本上说是不同的,因为它将任务提交给commonPool执行器服务。这意味着增量代码发生在捕获局部变量的lambda中。为了使其工作,编译器必须将其转换为附加到lambda的实例变量。这在编译器证明循环可以安全消除方面混水摸鱼。

然而,即使您考虑了所有这些事情,您的代码也是以一种基本的方式被破坏的:您不需要等待启动协同机制的完成。因此,在修复了上面的问题并使循环做了一些非常重要的工作之后,您就会发现coroutine示例报告了不依赖于循环迭代次数的常数时间。

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66595600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档