DEV Community

Discussion on: Java 8 tutorial: Master stream API and beyond

Collapse
 
cicirello profile image
Vincent A. Cicirello • Edited

There is significant overhead associated with Java 8 streams. Here is a good explanation of where some of that overhead comes from. Java implements a lambda function via the JVM creating a class at runtime the first time the lambda is called that implements the relevant interface. If that lambda is used enough, the JIT eventually kicks in, and any negative impact on performance will eventually disappear overall. You are necessarily using lambdas with streams, sometimes multiple of them (e.g. one for a filter, another for a map, yet another for the forEach). Each results in a new class created by JVM when first encountered. If you are doing so for a small collection, especially if that code utilizing streams is called a small number of times, the JIT won't have the opportunity to make up the loss in performance. For very large collections, or if streams used in a hot-spot, the JIT will have the opportunity to compile those lambdas, eliminating any negative performance impact.

Note that I'm not arguing against using streams. But you need to use them wisely, and recognize that there is overhead.

Collapse
 
khmarbaise profile image
Karl Heinz Marbaise

Note that I'm not arguing against using streams. But you need to use them wisely, and recognize that there is overhead.

Use whatever makes your code best readable. And do not think about performance or internalls... If you really see a performance issue based on measuring than identify the root cause and fix it (assuming that you have unit tests)...

Apart from that using more recent versions of JDK's like JDK11, 17 (or currently JDK19) ... reduces that "overhead"

Thread Thread
 
cicirello profile image
Vincent A. Cicirello • Edited

The overhead doesn't go away with Java 17 (it also isn't reduced by Java 17 at least not to affect measurements), which I use for my projects. It probably doesn't go away with 19 either, but I stick to LTS versions so can't say from experience.

If you measure (instead of assuming that others have not), you will see that streams are slower (as much as 2 to 4 times slower from my measurements depending upon a variety of factors). If performance doesn't matter for your application then don't worry about that and use streams. If performance does matter, then the root cause you say to look for may well be streams. It depends.

Here is a link to a comparison from Oracle: blogs.oracle.com/javamagazine/post.... The iterative version with a for loop runs in about a third of the time as sequential streams. And surprisingly about half the time as parallel streams. I'm guessing the latter relates to the task in their comparison. Aside from the surprising parallel result, Oracle's comparison using Java 17 is consistent with every other benchmarking I've seen with Java streams vs loops, as well as consistent with my own benchmarking. Java's sequential streams are significantly slower than the equivalent with a loop.