简体   繁体   中英

Why Kotlin Coroutine is taking longer time

I have two programs

  1. with coroutine

I have 3 loops and i tried assigning each loop to a coroutine for quick execution.

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. Without Coroutine
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

I have used timer to calculate the exectution time, but the coroutine code is taking longer.

Why is it working like this, how can i make the coroutine part faster?

Your code disregards a great deal of concerns that make your two examples very different.

First of all, you should never trust the timing of the very first run through the code. This is the time when all the heavyweight class initialization happens, including the initialization of the classes you touch indirectly by calling a library function.

Second, you also ignore all the optimizations the JIT compiler does to the bytecode. Most important in your case is that the code does nothing but increment local variables without using them afterwards. The JIT compiler will be happy to entirely delete your loops. Even if you use the results afterwards, the compiler may be able to do some simple reasoning on what the resulting value will be after 1,000,000 increments.

Your first example, with coroutines, is fundamentally different in that it submits tasks to the commonPool executor service. This means your incrementing code happens within a lambda that captures your local variable. In order to make it work, the compiler must transform it into an instance variable attached to the lambda. This muddies the waters in terms of the compiler proving the loop can be safely eliminated.

However, even if you accounted for all these things, your code is broken in an elementary way as well: you don't await for the completion of the launched coroutines. So after you fix the above issues and make the loops do some non-trivial work whose results you actually check for, you'll find that the coroutine examples report constant time that doesn't depend on the number of loop iterations.

I think what best explains your current results is the initialization costs. Just put a big outer loop over the whole code and the coroutine example will appear to perform much better than now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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