Is there a performant way to transform `List<Fl...
# coroutines
m
Is there a performant way to transform
List<Flow<T>>
into
Flow<List<T>>
where
List<T>
contains the latest value of each
Flow<T>
at the same index.
combine()
is not an option.
I’ve written a simple one, in case someone needs it: https://gist.github.com/fluidsonic/4330ebda9942c57a6660fadba1145362
m
I’m not sure why comine is not an option. I don’t know about performance but I recently had to do this and I used something like this.
Copy code
fun <T> Iterable<Flow<T>>.unwrap(): Flow<List<T>> {
  val emptyFlow = emptyFlow<List<T>>()
  return fold(emptyFlow) { flows, flow ->
    if (flows === emptyFlow) {
      flow.map(::listOf)
    } else {
      flows.combine(flow) { group, item -> group + item }
    }
  }
}
m
Because the parallel combine is slow as heck: https://github.com/Kotlin/kotlinx.coroutines/issues/2296
m
Ok, thanks for the link 🙂
b
it's slow because under the hood it uses "fair channels" that calls
yield
each time when element offered with fast path. As far as I understand it's necessary for sequential flows.
when you write
listOf(flow1,flow2,flow3).combine()
you can expect that it will use order of these flows. With your extension you can't expect this. It may lead to the following behavior:
Copy code
time:   | 1 | 2 | 3 | 4 | 5
flow1:  | A |   | B |   | 
flow2:  | w | x | y | z | 
combine:| Aw| Ax| Ay| Az| Bz| <-your extension
stdlib: | Aw| Ax| Bx| By| Bz|
m
What would such a time unit be in Kotlin? There is no time frame defined in which values from multiple flows would be merged 🤔 Or is it elements that happen to be collectible in the same “tick”?
Or expressed differently: How is it defined that “B” and “y” arrive at the same time?
b
Or is it elements that happen to be collectible in the same “tick”?
yes, it's just shows that at some time called "3" B and y are ready for collect
m
Okay. So if that’s really necessary then it may be better to have two operators, one which is fast and doesn’t care about that, and one that is slow and maintains order if elements arrive “simultaneously”. And clearly document each 🙂