Kotlin 科特林合作项目中的奇怪加速?
我有两个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
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与在没有显式调度器的情况下运行不同吗?