Is it good practice, if you're in a suspending fun...
# serialization
e
Is it good practice, if you're in a suspending function, to use
withContext(Dispatchers.Default) { Json./*... some (de)serialization function*/() }
, so that (de)serialization happens on a thread optimised for CPU-heavy work? Or is there built-in coroutine support in kotlinx.serialization, so that I can just call suspending versions of (de)serialiszation functions?
c
Does your server have two kinds of cores for CPU and IO work?
e
This is on mobile Android devices, so there are likely multiple cores and certainly threads. Not sure about different kinds
c
There is no standard dispatcher with just the "faster CPU cores", maybe the Android libraries have that somewhere?
e
I only know that the
IO
dispatcher on Android is optimised for IO work. The
Main
dispatcher is not to be blocked. And then there's the
Default
dispatcher for CPU work. And the coroutines lib smartly can switch between these dispatchers by (sometimes) not switching JVM threads underneath for efficiency. So if I'm about to serialise something to post in a request, I think I could:
Edit: improved version below, ignore this message
Copy code
val serialzedData = withContext(Dispatchers.Default) { Json.encodeToString(data) }
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { post(serializedData) }
c
Is your data so large that it makes a difference to serialize it somewhere else than the IO dispatcher?
e
Probably not 😅 though in this project I actually don't know the data being (de)serialized. It's dynamic But I'm wondering still (hence my original question): is it a good idea to do this by default?
Note what I said earlier (and see the 'Implementation note' here: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-i-o.html): The
IO
and
Default
dispatchers share underlying threads and do a best effort to prevent thread switches
Improved version:
Copy code
withContext(Dispatchers.Default) {
    val serialzedData = Json.encodeToString(data)
    withContext(<http://Dispatchers.IO|Dispatchers.IO>) { post(serializedData) }
}
To ensure that
post
happens from within the IO dispatcher in the Default dispatcher, so that that optimisation kicks in
(And I know that the context switch to
IO
should probably be encapsulated inside of the
post
function, so that all these context switches are less visible and the code looks more streamlined)