I had a discussion with another java programmer about processing collections with java 8 streams and she mentioned that she prefers classical loops because streams are slower. This is the perfect start for a hot debate about which one is better and the best way to continue it is to have facts. In previous post I parsed a pretty large text file into a list so I decided to extend foods parsing code and process this list in three ways: the old fashion for-each loop, sequential stream and parallel stream. The result list after parsing contains almost 9000 elements and the processing consists in computing the number of calories in a common household measure like the tablespoon starting from the number of calories in 100g.

Each line from the original file is saved in an instance of

1

2

3

4

5

6

7

8

9

10

11

12

13

14

/**

* It contains values from ABBREV.txt file

*/

data classAbbrev(val ndbNo:String,

val shrtDesc:String,

val energKcal:Int){

vargmWt1:Double=0.0;

vargmWtDesc1:String="";

vargmWt2:Double=0.0;

vargmWtDesc2:String="";

}

the result of the tranformation is kept in an instance of

1

2

3

4

5

6

7

8

9

10

/**

* It contains Kilo calories for 100g, and common house hold weights

*/

data classAbbrevKcal(val ndbNo:String,

val energKcal:Int,

val gmWt1Kcal:Double,

val gmWt2Kcal:Double){

}

and the transformation is done by

1

2

3

4

5

6

fun convert(abbrev:Abbrev):AbbrevKcal=AbbrevKcal(

abbrev.ndbNo,

abbrev.energKcal,

abbrev.energKcal*abbrev.gmWt1/100,

abbrev.energKcal*abbrev.gmWt2/100)

I used kotlin to implement needed data classes because in kotlin is very easy to define them and it is also very easy to mix kotlin with java. I used jmh to create the benchmark and the code is below:

In this case the implementation with parallel stream is ~ 3 times faster than the sequential implementations. Also there is no significant difference between fore-each loop and sequential stream processing.

My conclusions after this test are to prefer cleaner code that is easier to understand and to always measure when in doubt.