[PATCH] Collectors.counting() does unnecessary boxing on every accumulation

Tagir F. Valeev amaembo at gmail.com
Thu Sep 17 06:02:01 UTC 2015


Hello!

Could you please consider the following very simple patch to
Collectors.counting() implementation?

diff --git a/src/java.base/share/classes/java/util/stream/Collectors.java b/src/java.base/share/classes/java/util/stream/Collectors.java
--- a/src/java.base/share/classes/java/util/stream/Collectors.java
+++ b/src/java.base/share/classes/java/util/stream/Collectors.java
@@ -504,7 +504,7 @@
      */
     public static <T> Collector<T, ?, Long>
     counting() {
-        return reducing(0L, e -> 1L, Long::sum);
+        return summingLong(e -> 1L);
     }
 
     /**

===== END-OF-PATCH =====

Current implementation uses reducing collector which is not
primitive-specialized, thus on every accumulation event the current
Long value is unboxed, then boxed again (inside one-element Object[]
array created in "reducing"). As this collector is intended for
downstream use, these boxes are usually stored as map values for
different keys, thus JIT-compiler has practically no chance to
optimize out these operations. In contrast summingLong is more
performant as it uses the primitive long[] one-element array and
modifies it in-place.

Though it's quite obvious that this change should improve the
performance, I did some simple benchmark here:
https://gist.github.com/amaembo/6d9c0e74fec99c665620
Using summingLong can be up to 30% faster.

With best regards,
Tagir Valeev.




More information about the core-libs-dev mailing list