4 ms·
Any thoughts on performance differences between loops and streams? My gut says that loops, being a more primitive concept are likely to perform better in most
by SeanDav 12y ago
Any thoughts on performance differences between loops and streams?
My gut says that loops, being a more primitive concept are likely to perform better in most situations. In addition I just find loops easier to reason about, but that is probably purely personal.
- kasey_junk 12y agoI have not looked at the java8 constructs surrounding this. This is largely implementation specific. For instance, the .net LINQ to object implementations are largely syntactic sugar around loops (that is they compile to the same thing). Similarly, for loops are frequently just syntactic sugar around while loops.
- azth 12y agoHave they improved the implementation recently? I have not benchmarked myself, but according to [1], they are slower than the equivalent loop-based code. [1] http://arxiv.org/pdf/1406.6631v2.pdf
- kasey_junk 12y agoThis paper rightly points out that there will be overhead of object creation and potentially virtual calls (though that will be very JIT dependent). That said, my cursory examination (and it was very cursory) of their benchmark for C# is that they are really benchmarking the time difference between the iterator of an IEnumerable (or maybe IList, don't have an ability to decompile it right now) and the highly optimized case of looping through an array (which is literally one of the most highly optimized tasks on modern commodity hardware). On one hand, it does prove their point that in certain very specialized cases (looping through an array with no abstraction atop it), you will have significant performance penalties in the generic iterator case. On the other, I'm not sure I would attribute this to LINQ. I'm reasonably certain (and in these cases the space "reasonably" represents could have a truck driven through it) if you were to write the same code as a foreach loop using the same iterator and generic collections you wouldn't see significant performance differences. I'm definitely confident in most "real world" uses, where you are already using generic collections and iterators, you should bias towards using the LINQ implementation (assuming you believe it is better code) until definitive performance testing proves otherwise. For instance, in the case of the sum of squares, that looks like classic loop unrolling optimizations not being applied which any indirection in the looping code can prevent. Further, they show that there already exist optimization libraries that can eliminate much of the overhead. I will say, I'm quite impressed by the java results on this benchmark. Also, I didn't write any tests to prove any of this, so could be wildly off the mark. Further, I've spent more time than i ever wanted either hand translating or writing macros to, translate high level collections code into while loops. But that was in an extremely performance sensitive environment.
- hoopism 12y agoFrom my understanding the big win that is not discussed in the article is the parallelism. Stream operations can occur concurrently potentially improving performance. EDIT: There is more in-depth discussion of this in this thread. I missed it.
- acaloiar 12y agoIt should be noted that one must assume a performance penalty when calling stream() on a Collection, as doing so creates a new Stream object. Within inner loops and for small Collections I recommend avoiding stream() altogether if performance is a concern. Furthermore, while tempting, Stream.parallel() should only be called when it is certain that the additional cost of a ForkJoinPool instance creation can be amortized over the duration of the lambda's runtime. With that said, I welcome Streams and other FP concepts to Java.
- eveningcoffee 12y agoYou have to measure this (carefully). My gut feeling is that assuming streams are (in the end, but without looking) based on the loops, and Java JIT has great inlining capacity, there is really no measurable difference. Again, one actually should measure it to conclude anything.