Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 科特林合作项目中的奇怪加速?_Kotlin_Concurrency - Fatal编程技术网

Kotlin 科特林合作项目中的奇怪加速?

Kotlin 科特林合作项目中的奇怪加速?,kotlin,concurrency,Kotlin,Concurrency,我有两个kotlin代码片段,用于测量线程的启动时间 第一: import kotlinx.coroutines.* fun main() { runBlocking { for(i in 0..99){ val start = System.nanoTime() launch { val time = System.nanoTime() - start println("St

我有两个kotlin代码片段,用于测量线程的启动时间

第一:

import kotlinx.coroutines.*
fun main() {
 runBlocking {
     for(i in 0..99){
        val start = System.nanoTime()
           launch {
               val time = System.nanoTime() - start
               println("Starttime: %,d".format(time))
          }
       }
    }
  }
suspend fun main() {
    // dummy calls to preload classes before measuring
    val s = System.nanoTime()
    GlobalScope.launch { println("starting %,d".format(s)) }.join()

    repeat(100) { i ->
        val start = System.nanoTime()
        GlobalScope.launch {
            val time = System.nanoTime() - start
            println("Starttime[$i]: %,d".format(time))
        }
    }
    delay(1000) // wait for all coroutines to print result
}
这段代码从打印35.000.000范围内的内容开始,经过100次迭代,其中值变大,结束于75.000.000左右。 现在如果我运行这个代码

import kotlinx.coroutines.*
fun main() {
     runBlocking {
         val list:MutableList<Long> = MutableList<Long>(100, {0})
         for(i in 0..99){
             val start = System.nanoTime()
             launch {
                   list[i] = System.nanoTime() - start
                 }
      }
    delay(1000) // wait for all coroutines to have stored result
    list.forEach{ println("Starttime: %,d".format(it)) }
 }
}
导入kotlinx.coroutines*
主要内容(){
运行阻塞{
val list:MutableList=MutableList(100,{0})
对于(0..99中的i){
val start=System.nanoTime()
发射{
list[i]=System.nanoTime()-start
}
}
delay(1000)//等待所有协程都存储结果
list.forEach{println(“Starttime:%,d”.format(it))}
}
}
这段代码显然更快,因为print语句没有包含在发布中。但还有其他一些行为是奇怪的。它从大约50000.000开始,直接跳到17.083.000,然后缓慢地上升到29.507.300,最后结束


所以我的问题是:为什么第一段代码恶化得如此之快,并且很快变得很慢,而第二段代码能够更快,而且它不会随着时间的推移而变得更慢,因为我添加了更多的协程?

你犯了一个小错误,没有在测量时间之前预加载类,所以结果是不正确的。您还应该打印作业索引,以便查看作业实际完成的顺序

我建议修改您的代码示例:

第一:

import kotlinx.coroutines.*
fun main() {
 runBlocking {
     for(i in 0..99){
        val start = System.nanoTime()
           launch {
               val time = System.nanoTime() - start
               println("Starttime: %,d".format(time))
          }
       }
    }
  }
suspend fun main() {
    // dummy calls to preload classes before measuring
    val s = System.nanoTime()
    GlobalScope.launch { println("starting %,d".format(s)) }.join()

    repeat(100) { i ->
        val start = System.nanoTime()
        GlobalScope.launch {
            val time = System.nanoTime() - start
            println("Starttime[$i]: %,d".format(time))
        }
    }
    delay(1000) // wait for all coroutines to print result
}
第二:

suspend fun main() {
    // dummy calls to preload classes before measuring
    val s = System.nanoTime()
    GlobalScope.launch { println("starting %,d".format(s)) }.join()

    val list: MutableList<Long> = MutableList<Long>(100, { 0 })
    repeat(100) { i ->
        val start = System.nanoTime()
        GlobalScope.launch {
            list[i] = System.nanoTime() - start
        }
    }
    delay(1000) // wait for all coroutines to have stored result
    list.forEachIndexed { i, it -> println("Starttime[$i]: %,d".format(it)) }
}
suspend fun main(){
//测量前预加载类的伪调用
val s=System.nanoTime()
GlobalScope.launch{println(“起始%.d”).format(s))}.join()
val list:MutableList=MutableList(100,{0})
重复(100){i->
val start=System.nanoTime()
环球镜发射{
list[i]=System.nanoTime()-start
}
}
delay(1000)//等待所有协程都存储结果
list.forEachIndexed{i,it->println(“Starttime[$i]:%,d.”格式(it))}
}
第一个示例明显“恶化”,因为您只需立即堆积100个作业,而它们需要大量时间访问
System.out
以执行打印操作。您也可能会体验到他们很可能没有按顺序打印[索引]


第二个示例或多或少比较稳定,因为作业不执行任何繁重的操作,所以
分派器中通常有一个空闲线程。默认情况下,
池可以立即执行启动块。

谢谢!但是,当我没有指定一个调度程序时,整个程序不就是在主线程上运行吗?@n00bster no,默认情况下使用
Dispatchers.Default
。在主线程上运行没有任何意义,因为它只会阻塞.hmm,但是如果我在打印中包含一个thread.currentThread的打印,那么在没有任何调度程序的情况下启动将显示mainthread,而Dispatchers.default将在线程之间交替?如果您将
launch
用作
runBlocking
的子线程,它将继承其协同程序上下文,因此它确实将以阻塞方式执行。好的,那么在我的示例中,Dispatchers.default与在没有显式调度器的情况下运行不同吗?