performance - Kotlin:coroutineScope 比 GlobalScope 慢

标签 performance kotlin parallel-processing coroutine kotlin-coroutines

我正在学习协程,我遇到了以下令人惊讶的(对我而言)行为。我想要一张平行 map 。我考虑了4个解决方案:

  • 刚刚map , 无并行性
  • pmap来自 here .
  • 修改第 2 项:我删除了 coroutineScope并使用 GlobalScope .
  • Java的parallelStream .

  • 编码:
    import kotlinx.coroutines.*
    import kotlin.streams.toList
    import kotlin.system.measureNanoTime
    
    inline fun printTime(msg: String, f: () -> Unit) =
        println("${msg.padEnd(15)} time: ${measureNanoTime(f) / 1e9}")
    
    suspend fun <T, U> List<T>.pmap(f: (T) -> U) = coroutineScope {
        map { async { f(it) } }.map { it.await() }
    }
    
    suspend fun <T, U> List<T>.pmapGlob(f: (T) -> U) =
        map { GlobalScope.async { f(it) } }.map { it.await() }
    
    
    fun eval(i: Int) = (0 .. i).sumBy { it * it }
    
    fun main() = runBlocking {
        val list = (0..200).map { it * it * it }
        printTime("No parallelism") { println(list.map(::eval).sum()) }
        printTime("CoroutineScope") { println(list.pmap(::eval).sum()) }
        printTime("GlobalScope") { println(list.pmapGlob(::eval).sum()) }
        printTime("ParallelStream") { println(list.parallelStream().map(::eval).toList().sum()) }
    }
    

    输出(无总和):
    No parallelism  time: 0.85726849
    CoroutineScope  time: 0.827426385
    GlobalScope     time: 0.145788785
    ParallelStream  time: 0.161423263
    

    如您所见,使用 coroutineScope几乎没有增益,而GlobalScope它的运行速度与 parallelStream 一样快.是什么原因?我可以有一个解决方案,它具有 coroutineScope 的所有优点吗?具有相同的速度增益?

    最佳答案

    范围仅间接涉及您观察到的差异。
    GlobalScope是一个定义自己的调度器的单例,它是 Dispatchers.Default .它由线程池支持。
    coroutineScope没有定义自己的调度程序,所以你从调用者那里继承它,在这种情况下是由 runBlocking 创建的调度程序。 .它使用它被调用的单线程。

    如果更换 coroutineScopewithContext(Dispatchers.Default) ,你会得到相同的时间。这实际上是您应该如何编写它(而不是 GlobalScope ),以便在面对某些并发任务可能失败时获得理智的行为。

    关于performance - Kotlin:coroutineScope 比 GlobalScope 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55531464/

    相关文章:

    android - Kotlin addTextChangeListener lambda?

    java - 如何从 Firebase 检索不同对象类型的列表?

    xml - Windows Phone 7 - 加载一个大的 xml 文件

    缓存 malloc 性能改进

    jquery - 延迟加载 - $(document).准备好了吗?

    asp.net - 多次往返数据库,或所有数据/过滤器?

    generics - 如何在 Kotlin 中将多个 Upper Bounds 语法与委托(delegate)语法结合起来

    python - Python 中的多处理 : Numpy + Vector Summation -> Huge Slowdown

    java - Executors 类中的 newSingleThreadExecutor() 方法

    c - 中止 MPI 中所有进程的执行