Request for tracking down C1 optimizations: handwritten cartesian product similar to flatmap/map performance!

Paul Sandoz paul.sandoz at oracle.com
Fri May 30 08:40:17 UTC 2014


On May 29, 2014, at 7:55 PM, Aggelos Biboudis <biboudis at gmail.com> wrote:
> Hello all,
> 
> I would like to ask you something regarding C1 compilation (VM options: -Xms769m -Xmx769m -XX:-TieredCompilation) of a Cartesian product stream operation with the new stream API. 
> I have two versions of this computation, one handwritten and one with flatmap/map. It is remarkable that these two have similar performance so I would like to trace-back the JIT compilation decisions (apart from inlining), and more specifically if escape analysis has any effect.
> 
> ...
> 
> valuesHi = IntStream.range(0, 10000).mapToLong(i -> i).toArray();
> valuesLo = IntStream.range(0, 1000).mapToLong(i -> i).toArray();
> 

Tip: you can also use LongStream.range(0, N).toArray();


> @GenerateMicroBenchmark // -> 4.984 ms / op on avg
> public long cartSeq() {
>    long cart
>          = LongStream.of(valuesHi)
>             .flatMap(d -> LongStream.of(valuesLo).map(dP -> dP * d))

The function of long -> LongStream passed to the flatMap operation will create two objects per call: an instance of LongStream; and an instance of Spliterator. The map operation is passed a capturing lambda so on each call it will create an instance of LongUnaryOperator.

My hunch was, unless there is something else dominating, there some form of scalar replacement is going on. However, is it reasonable to assume that the difference of 700us is due to the cost of object allocations? To be sure one would need to look at the generated code.

To factor out array reads you might want to measure:

        long cart
                = LongStream.range(0, 10000)
                .flatMap(d -> LongStream.range(0, 1000).map(dP -> dP * d))
                .sum();

Paul.



>             .sum();       
>    return cart;
> }
> 
> @GenerateMicroBenchmark // -> 4.258 ms / op on avg
> public long cartBaseline() { 
>     long cart = 0;
>     for (int d = 0 ; d < valuesHi.length ; d++) {
>         for (int dp = 0 ; dp < valuesLo.length ; dp++){
>         cart += valuesHi[d] * valuesLo[dp];
>         }
>     }
>     return cart;
> }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20140530/be1d25ba/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 841 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20140530/be1d25ba/signature.asc>


More information about the hotspot-compiler-dev mailing list