Я новичок в Kotlin и сопрограммах и пытаюсь понять API сопрограмм, поэтому вполне возможно, что я делаю что-то не так. Итак, у меня есть список объектов определенного типа, и я пытаюсь применить длительную обработку к каждому из этих объектов.
val listOfFoos = listOf(Foo(1), ..., Foo(n))
listOfFoos.forEach { longRunningJob(it) }
fun longRunningJob(foo: Foo) {
runBlocking{
delay(2000) //hardcoded delay for testing
}
//do something else
}
Конечно, это идеальный кандидат для одновременного запуска, поэтому здесь используются старые добрые потоки:
listOfFoos.map { thread(start = true) { longRunningJob(it) } }.forEach { it.join() }
Когда я измеряю время его выполнения с помощью measureTimeMillis
, это дает мне около 2 секунд, что кажется совершенно нормальным, поскольку каждый longRunningJob
работает параллельно.
Но сопрограммы намного лучше, поскольку у них нет таких издержек, как потоки для переключения контекста. Итак, моя реализация с использованием сопрограмм:
val deferredResults =
listOfFoos.map { GlobalScope.async { longRunningJob(it) } }
runBlocking {
deferredResults.awaitAll()
}
Но эта реализация завершает выполнение примерно за 4 секунды, а это совсем не то, чего я ожидал, и если я добавлю больше элементов в список, время выполнения также увеличится.
Так что я здесь не так делаю?