Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin flatMap - map

Tags:

kotlin

Say I have a list of size 30k elements, and I would like to perform an operation on all possible pairs within a list. So I had:

 list.asSequence().flatMap { i -> 
         list.asSequence().map { j -> /* perform operation here */ }
 }

Question 1: Is there anything that I can use as an alternative? (Such as applicative functors).

I also noticed that this flatMap-map operation is significantly slower than the imperative loop version. (perhaps due to closures?)

for(i in list){
    for(j in list){

    }
}

Question 2: Is there a way to improve the performance of the flatMap/map version?

like image 347
Francis Fredrick Valero Avatar asked Dec 06 '15 01:12

Francis Fredrick Valero


Video Answer


2 Answers

Some alternatives with performance impacts:

  1. com.google.common.collect.Sets.cartesianProduct(java.util.Set...): "Returns every possible list that can be formed by choosing one element from each of the given sets in order; the 'n-ary Cartesian product' of the sets."
    • This requires your list elements to be unique. If they're not then you'd have to wrap each element in a unique object so that they can all be added to the input set.
    • In my testing, however, I've found it to be slower than the flatMap/map solution. :-(
  2. forEach/forEach: As you simply want to perform an operation on each pair then you don't actually need to use flatMap or map to transform the list so you can use forEach/forEach instead:

    list.forEach { i ->
        list.forEach { j -> /* perform operation here */ }
    }
    
    • In my testing I've found this to be slightly faster than the for/for solution. :-)

If you do need to transform the list then your flatMap/map solutions appears to be the best solution.

like image 106
mfulton26 Avatar answered Sep 17 '22 16:09

mfulton26


Answering to the question 2, we're considering to add flatMap overload which doesn't create closures for each element in the outer collection/sequence: https://youtrack.jetbrains.com/issue/KT-8602

But in case if you want to perform some side effects on each pair, rather than transforming the sequence, I'd advice to stick with for-loops or inlined forEach lambdas, which is effectively the same.

like image 29
Ilya Avatar answered Sep 16 '22 16:09

Ilya