Kotlinのリスト操作の中でCoroutinesのasync()で並列処理を実行した結果を待ち合わせる方法

タイトルが非常に分かりづらくて申し訳ないです🙇‍♂️
Kotlinのリスト操作の中でネットワーク通信のような時間のかかる処理を並列に実行したい場面があったのですが、Coroutinesを使ってその結果を待ち合わせる方法が最初分からなかったので、本記事はそのメモです。

結論としては、kotlinx-coroutines-coreライブラリの中にawaitAll()という拡張関数があり、こちらがそのまま使えました。

kotlin.github.io


簡単なサンプルコードを以下に記載します。
引数として受け取った値を1秒後に返すlazy()という中断関数を定義し、sampleDataというリストに対する操作の中でlazy()を呼び出します。

map()の中でlazy()を直接呼び出す場合、リストのアイテム数が増えるほど処理の完了時間が延びていきます。
一方、map()の中でasync()でコルーチンを起動し、lazy()をその中で呼び出し、awaitAll()でその結果を待ち合わせる場合、リストのアイテム数が増えても処理の完了時間にはさほど影響がありません。

// ※ 何かしらのCoroutineScope内という前提で書いています

val sampleData = listOf(1, 2, 3, 4, 5)

val time1 = measureTime {
  val result = list.map { async { lazy(it) } }.awaitAll()
}
println(time1)  // 約1秒となる

val time2 = measureTime {
  val result = list.map { lazy(it) }
}
println(time2)  // 約5秒となる

// 引数として受け取った値を1秒後に返す中断関数
suspend fun lazy(n: Int): Int {
  delay(1000)
  return n
}