[PATCH] Collectors.counting() does unnecessary boxing on every accumulation
Paul Sandoz
paul.sandoz at oracle.com
Thu Sep 17 09:21:46 UTC 2015
Hi Tagir,
Thanks, looks good.
I created:
https://bugs.openjdk.java.net/browse/JDK-8136686
and i also included an update to a test.
Assuming no further review comments i will commit tomorrow.
Paul.
diff -r 4be07e0eb9b6 test/java/util/stream/test/org/openjdk/tests/java/util/stream/CountTest.java
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CountTest.java Thu Sep 17 10:37:39 2015 +0800
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CountTest.java Thu Sep 17 11:21:16 2015 +0200
@@ -31,6 +31,7 @@
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
@@ -61,6 +62,12 @@
expectedResult(expectedCount).
exercise();
+ // Test counting collector
+ withData(data).
+ terminal(s -> s, s -> s.collect(Collectors.counting())).
+ expectedResult(expectedCount).
+ exercise();
+
// Test with stateful distinct op that is a barrier or lazy
// depending if source is not already distinct and encounter order is
// preserved or not
On 17 Sep 2015, at 08:02, Tagir F. Valeev <amaembo at gmail.com> wrote:
> 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