介绍

Kotlin 的协程,我不知道与线程相比有什么明显的好处,也没有过多地使用它们。
但是,这一次,协程在我想尽快处理大量记录的情况下非常有用。

用完多核

大多数现代 CPU 都有多个内核,但单线程程序只能使用一个内核。
但是,对于可以并行处理的任务,使用所有 CPU 内核并行处理是最快的。

为了使用所有 CPU 内核进行并行处理,需要创建与内核数量一样多的线程,并妥善管理这些线程并进行并行处理,这非常耗时。
但是 Kotlin 的协程让它变得简单。

代码示例

从代码输入。
通过下面的几行代码,您可以使用所有 CPU 内核进行并行处理。

协程并行示例
import kotlinx.coroutines.*

fun <T> operateItems(items: Collection<T>, operate: (T) -> Unit) {
    runBlocking {
        val scope = CoroutineScope(Dispatchers.Default)
        items.map {
            scope.async {
                operate(it)
            }
        }.awaitAll()
    }
}

简单解释一下代码,例如,如果要并行处理 100,000 条记录,请将 100,000 条记录传递给参数 items,并将处理每条记录的函数传递给参数 operate

对于每条记录,并行处理在由async 函数创建的协程中完成,awaitAll 等待直到所有处理完成。

协程的线程管理

协程是调度员决定如何使用线程。
协程不一定是多线程的,根据 Dispather 可以是单线程的。

代码示例使用Dispatchers.Default 作为 Dispatcher。这个 Dispatcher 创建和池化与 CPU 内核数量一样多的线程,并在这些线程之间分配协程处理。
这允许使用所有 CPU 内核进行并行处理。

Dispatcher.Default 的描述

在代码示例的示例中,以异步方式编写的operate(it) 将在 CPU 内核可用时按顺序执行。
比如 CPU 有 4 个核心,第一个操作会执行 4 次,下一个操作会在其中一个操作完成后立即执行,这样 4 个操作始终会并行执行。

速度测量

我在一台 6 核 CPU 机器上运行了上面的协程代码,并将速度与单线程处理进行了比较。
使用 6 个内核,希望协程应该比单线程快 6 倍。

速度是用两种模式来衡量的,一种是大约需要 100ms 的过程被执行 1000 次,另一种是大约需要 10ms 的过程被执行 10000 次。

执行 1000 毫秒处理 1000 次的代码示例
operateItems((1..1000).toList()) {
    processTakes100ms() // Math.pow()を大量実行して100msくらいかかるよう調整した関数
}
单线程 协程
100ms处理×1000次 99.4s 17.4s
10ms处理×10000次 100.4s 17.5s

单线程大约需要 100 秒的处理,使用协程大约需要 17.5 秒,比单线程快 5.7 倍它的速度差不多。
它比 6x 有点短,但这是可以接受的开销。

特别是后者生成了 10,000 个协程,但它并没有减慢多少,我能够意识到协程的优势在于它们是轻量级的。

概括

  • Coroutine Dispathcers.Default 使用所有 CPU 内核
  • 协程轻量级,可量产

原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308623896.html

相关文章:

  • 2021-11-10
  • 2022-01-01
  • 2022-12-23
  • 2022-12-23
  • 2021-11-26
  • 2022-12-23
  • 2021-10-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-31
  • 2021-06-22
  • 2021-12-19
  • 2021-09-05
相关资源
相似解决方案