1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.openjdk.bench.java.util.stream.ops.value;
  24 
  25 import org.openjdk.jmh.annotations.Benchmark;
  26 import org.openjdk.jmh.annotations.BenchmarkMode;
  27 import org.openjdk.jmh.annotations.Mode;
  28 import org.openjdk.jmh.annotations.OutputTimeUnit;
  29 import org.openjdk.jmh.annotations.Param;
  30 import org.openjdk.jmh.annotations.Scope;
  31 import org.openjdk.jmh.annotations.Setup;
  32 import org.openjdk.jmh.annotations.State;
  33 
  34 import java.util.concurrent.TimeUnit;
  35 import java.util.concurrent.atomic.LongAdder;
  36 import java.util.function.LongConsumer;
  37 import java.util.stream.LongStream;
  38 
  39 /**
  40  * Benchmark for forEach() operations.
  41  */
  42 @BenchmarkMode(Mode.Throughput)
  43 @OutputTimeUnit(TimeUnit.SECONDS)
  44 @State(Scope.Thread)
  45 public class ForEach {
  46 
  47     /**
  48      * Implementation notes:
  49      *   - parallel version requires thread-safe sink, we use the same for sequential version for better comparison
  50      *   - operations are explicit inner classes to untangle unwanted lambda effects
  51      */
  52     @Param("100000")
  53     private int size;
  54 
  55     private LongConsumer b1, b2, b3;
  56     private LongAdder sink;
  57 
  58     @Setup
  59     public void setup() {
  60         sink = new LongAdder();
  61         b1 = new LongConsumer() {
  62             @Override
  63             public void accept(long v) {
  64                 sink.add(v);
  65             }
  66         };
  67         b2 = new LongConsumer() {
  68             @Override
  69             public void accept(long v) {
  70                 sink.add(v);
  71             }
  72         };
  73         b3 = new LongConsumer() {
  74             @Override
  75             public void accept(long v) {
  76                 sink.add(v);
  77             }
  78         };
  79     }
  80 
  81     @Benchmark
  82     public long seq_invoke() {
  83         LongStream.range(0, size).forEach(b1);
  84         return sink.sum();
  85     }
  86 
  87     @Benchmark
  88     public long seq_chain111() {
  89         LongStream.range(0, size).forEach(b1);
  90         LongStream.range(0, size).forEach(b1);
  91         LongStream.range(0, size).forEach(b1);
  92         return sink.sum();
  93     }
  94 
  95     @Benchmark
  96     public long seq_chain123() {
  97         LongStream.range(0, size).forEach(b1);
  98         LongStream.range(0, size).forEach(b2);
  99         LongStream.range(0, size).forEach(b3);
 100         return sink.sum();
 101     }
 102 
 103     @Benchmark
 104     public long par_invoke() {
 105         LongStream.range(0, size).parallel().forEach(b1);
 106         return sink.sum();
 107     }
 108 
 109     @Benchmark
 110     public long par_chain111() {
 111         LongStream.range(0, size).parallel().forEach(b1);
 112         LongStream.range(0, size).parallel().forEach(b1);
 113         LongStream.range(0, size).parallel().forEach(b1);
 114         return sink.sum();
 115     }
 116 
 117     @Benchmark
 118     public long par_chain123() {
 119         LongStream.range(0, size).parallel().forEach(b1);
 120         LongStream.range(0, size).parallel().forEach(b2);
 121         LongStream.range(0, size).parallel().forEach(b3);
 122         return sink.sum();
 123     }
 124 
 125 }