When working with coroutines should every call tha...
# coroutines
l
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
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
I disagree, unless you have a very strict definition of “blocking”. e.g. is
someArray.filter { ... }
a “blocking” operation in your opinion?
s
True, to clarify: In this example, with blocking I meant blocking a thread on an external resource.
t
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
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
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
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.