Map & flatmap: Kotlin is slower than Java - fixed


#1

I've tried to create a "a","b".."z","aa","ab","ac".."zz" data. here are to versions that create it the same way:

Java version:

 
static String[] letters = IntStream.rangeClosed(‘A’, ‘Z’).mapToObj(c -> String.valueOf((char) c)).toArray(String[]::new);

public static void javaWay() {
  Stream.of(letters).flatMap(letter -> Stream.of(letters).map(anotherLetter -> letter + anotherLetter));
}

Kotlin version:

 
val seq = ('a'..'z').map(Char::toString).toTypedArray()
fun kotlinWay() {
    val a = seq flatMap { seq map { char -> it + char } }
}

However, the kotlin version is much slower. 10,000 runs of the java version take ~47ms. 10,000 runs of the kotlin version take ~220ms.

Why does the Kotlin version is slower? Since the Kotlin version is based on inline, I thought it would be faster.


#2

In Java version you are using Streams which are lazy. Kotlin's map function is eager on an array. What if you replace "toTypedArray()" with "asSequence()"?


#3

And of course, javaWay actually does nothing except constructing a stream, because you are not even consuming the stream. You need to call Collect on a Stream and toList() on Kotlin sequence to actually compare something.


#4

If I change it to Sequence it create a new Sequence from the tranformation. so 4ms and it is faster than Java (47ms). but when consuming both to a list, the kotlin version is faster, 260ms compared to 350ms. However in java you can consume it to array. if you consume it to object[] it takes 260ms, but it takes 350ms to string[].

Thanks for helping :slight_smile: