I recently started comparing Java vs Kotlin performance and after fisrt try I already found some strange things.
I run a JHM benchmark on reducing a stream/list, as expected Java on stream was faster, but I noticed something else.
Stream<Long>.reduce(0L, (a, b) -> a + b);
Was a significantly slower than:
Stream<Long>.reduce( (a, b) -> a + b).orElse(0L);
The stream size was ~50k elements and input was the same (code can be found here: https://github.com/mariusz-zawadzki/kotlin-vs-java-jmh )
So my question is: can anyone point me to what happened in java 9 that improved the performance?
edit:
After looking into that a bit more I found no differences in other types of operations, only in Long. After chaning map(Long::valueOf) to mapToLong(Long::valueOf) there were no difference between java 8 and 9 in performance, nor there were any difference in reduce with or witout acumulator.
So my current guess is: there is an optimization in java 9 that somehow changes/knows how to change Stram to LongStream or get's rid of boxing/unboxing there. Conclusion: Stream.reduce(BinaryOperator) has the same performance as LongStream.reduce but only in java 9.
Java 9:
MyBenchmark.testJava thrpt 200 1234,795 ? 13,398 ops/s
MyBenchmark.testJavaAcumulator thrpt 200 1234,981 ? 1,994 ops/s
MyBenchmark.testJavaObject thrpt 200 1216,849 ? 6,028 ops/s
MyBenchmark.testJavaObjectAcumulator thrpt 200 933,023 ? 5,864 ops/s
Java 8
Benchmark Mode Cnt Score Error Units
MyBenchmark.testJava thrpt 200 1199,363 ? 3,870 ops/s
MyBenchmark.testJavaAcumulator thrpt 200 1195,621 ? 9,716 ops/s
MyBenchmark.testJavaObject thrpt 200 986,778 ? 4,852 ops/s
MyBenchmark.testJavaObjectAcumulator thrpt 200 993,045 ? 2,600 ops/s