Do Java 8 streams produce slower code than plain imperative loops?

Laziness is about how elements are taken from the source of the stream - that is on demand. If there is needed to take more elements - they will, otherwise they will not. Here is an example:

 Arrays.asList(1, 2, 3, 4, 5)
            .stream()
            .peek(x -> System.out.println("before filter : " + x))
            .filter(x -> x > 2)
            .peek(System.out::println)
            .anyMatch(x -> x > 3);

Notice how each element goes through the entire pipeline of stages; that is filter is applied to one element at at time - not all of them, thus filter returns a Stream<Integer>. This allows the stream to be short-circuiting, as anyMatch does not even process 5 since there is no need at all.

Just notice that not all intermediate operations are lazy. For example sorted and distinct is not - and these are called stateful intermediate operations. Think about this way - to actually sort elements you do need to traverse the entire source. One more example that is not intuitive is flatMap, but this is not guaranteed and is seen more like a bug, more to read here

The speed is about how you measure, measuring micro-benchmarks in java is not easy, and de facto tool for that is jmh - you can try that out. There are numerous posts here on SO that show that streams are indeed slower (which in normal - they have an infrastructure), but the difference is not that big to actually care.


QUESTION: Should I use old loop imperative approach if I'm looking for the best code performance?

Right now, probably yes. Various benchmarks seem to suggest that streams are slower than loops for most tests. Though not catastrophically slower.

Counter examples:

  • In some cases, parallel streams can give a useful speed up.

  • Lazy streams can provide performance benefits for some problems; see http://java.amitph.com/2014/01/java-8-streams-api-laziness.html

It is possible to do equivalent things with loops, you can't do it with just loops.

But the bottom line is that performance is complicated and streams are not (yet) a magic bullet for speeding up your code.

Is FP paradigm is just to make code "more concise and readable" but not about performance?

Not exactly. It is certainly true that the FP paradigm is more concise and (to someone who is familiar with it) more readable.

However, by expressing the using the FP paradigm, you are also expressing it in a way that potentially could be optimized in ways that are much harder to achieve with code expressed using loops and assignment. FP code is also more amenable to formal methods; i.e. formal proof of correctness.