Hi! I'm trying to parallelize some work, to improv...
# coroutines
i
Hi! I'm trying to parallelize some work, to improve performance. Am I doing it right?
Copy code
override fun foo(): List<String> =
    runBlocking {
        fooSuspended()
    }

suspend fun fooSuspended(): List<String> =
    coroutineScope {
        val res: List<Deferred<String?>> = (1..100).map { n ->
            async {
                doWork()
            }
        }
        res.mapNotNull { it.await() }
    }

fun doWork(): String? {
    Thread.sleep(500)
    return "hi"
}
o
you may want to specify a different dispatcher, otherwise it'll still be single-threaded due to `runBlocking`'s event loop. an easy way is
runBlocking(Dispatcher.Default) { ... }
i
thanks!!
o
another alternative is to specify the dispatcher as close to where it's actually needed as possible, in that case you could do
async(Dispatcher.Default) { ... }
and achieve a similar effect
i
"unresolved reference: Default" 😕
o
oh, it might be
Dispatchers
? been a bit
i
that's it!
Dispatcher
was from ok http
oh NICE went from 50s to 17s 🙂
d
Might be even faster with
<http://Dispatchers.IO|Dispatchers.IO>
since you're blocking with
Thread.sleep
.
i
in my actual code I'm doing computations. Maybe, still?
s
Instead of
res.mapNotNull { it.await() }
, what if you tried
res.awaitAll().mapNotNull()
? It shouldn’t matter much, since all `async`s are kicked off at the same time, but I’m curious 🙂
i
ok, tried out
IO
anyway and confirm that it's not good for computations. It duplicated the time 😅
d
Yeah, definitely worse for computation.
i
awaitAll().mapNotNull()
doesn't change the time
👍 1
but I'll use it, it seems more idiomatic
d
It is also less error-prone. Especially when laziness is involved.
👍 1
i
hmm this is very strange, the emulator (differently to the devices) is taking 2x longer with the coroutines...
compared to executing everything in the same thread
I guess the emulator doesn't support properly multiple cores?
d
That's my guess too.