https://kotlinlang.org logo
Title
l

Lilly

09/07/2021, 2:59 PM
When working with coroutines should every call that is fired from ViewModel layer run in another dispatcher, e.g.
Dispatchers.Default
. I'm asking because in my vms I have suspending fucntions as well as non-suspending functions (most of the time not expensive operations) and I'm wondering if there is a thumb of rule when to switch from
main
to
default
or should we always switch to default when we working outside the UI scope not matter how expensive the operation is?
s

streetsofboston

09/07/2021, 3:02 PM
There's is no real need to switch dispatcher in your VMs (or even your datasources/repos/etc for that matter), unless you call a blocking call. In that last case, switch to Dispatchers.IO and call that blocking function.
1
t

Tijl

09/07/2021, 4:02 PM
I disagree, unless you have a very strict definition of “blocking”. e.g. is
someArray.filter { ... }
a “blocking” operation in your opinion?
s

streetsofboston

09/07/2021, 4:12 PM
True, to clarify: In this example, with blocking I meant blocking a thread on an external resource.
t

Tijl

09/07/2021, 4:14 PM
someArray.filter
has input, output, and even if it does not wait for an external resource, it can still block your thread.
sure “just a little bit” is ok on your main thread, but you should not make a rule around this saying it’s ok
s

streetsofboston

09/07/2021, 4:21 PM
Usually it's ok. If you
someArray
is huge or you have some code that is long running, then switching to the Dispatchers.Default may be warranted indeed. But I've seen code that switches to Dispatchers.IO when it is just calling other suspending code (that does IO for example) and some simple transformations on the result. This not necessary. I have not done any performance measures, but always switching to another dispatcher for even a 'little bit' of code may cost more than it saves.
u

uli

09/07/2021, 4:24 PM
So for me the rule is, switch the thread only where you need it. I.e. make the scope of the
withContext
as small as possible. As @streetsofboston said, right around your blocking call. Or (@Tijl) of course around your computationally ‘expensive’ calls. And remember, no rule without exceptions 🙂 While switching between Default and IO dispatcher is almost free, switching between IO/Default and Main comes at a cost. So some aggregation of blocking calls might sometimes be needed. But his is nothing for premature optimization.
1
t

Tijl

09/07/2021, 5:35 PM
Keep in mind the ‘expensive’ calls don’t have to be that expensive, there are 120 fps screens out there nowadays (and climbing), and single core performance is not keeping pace with phones getting faster overall. there are common pitfalls like (de)serializing of objects that might “seem ok” during development but in real world usage leave your app a janky mess.