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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package org.openjdk.bench.vm.lambda.invoke;
  26 
  27 import org.openjdk.jmh.annotations.Benchmark;
  28 import org.openjdk.jmh.annotations.BenchmarkMode;
  29 import org.openjdk.jmh.annotations.Level;
  30 import org.openjdk.jmh.annotations.Mode;
  31 import org.openjdk.jmh.annotations.OperationsPerInvocation;
  32 import org.openjdk.jmh.annotations.OutputTimeUnit;
  33 import org.openjdk.jmh.annotations.Scope;
  34 import org.openjdk.jmh.annotations.Setup;
  35 import org.openjdk.jmh.annotations.State;
  36 import org.openjdk.jmh.infra.Blackhole;
  37 
  38 import java.util.concurrent.ThreadLocalRandom;
  39 import java.util.concurrent.TimeUnit;
  40 
  41 /**
  42  * evaluates invocation costs.
  43  *
  44  * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
  45  */
  46 @BenchmarkMode(Mode.AverageTime)
  47 @OutputTimeUnit(TimeUnit.NANOSECONDS)
  48 @State(Scope.Thread)
  49 public class Function1 {
  50 
  51     public interface FunctionII {
  52         int foo(int x);
  53     }
  54 
  55     public interface FunctionIL {
  56         int foo(Integer x);
  57     }
  58 
  59     public interface FunctionLL {
  60         Integer foo(Integer x);
  61     }
  62 
  63     private static final int LIMIT = 1024;
  64 
  65     private final int[]     dataI = new int[LIMIT + 1];
  66     private final Integer[] dataL = new Integer[LIMIT + 1];
  67 
  68     @Setup(Level.Iteration)
  69     public void setup() {
  70         for (int i = 0; i < dataI.length; i++) {
  71             int value = ThreadLocalRandom.current().nextInt(10001,420000); // bypass Integer.cache
  72             dataI[i] = value;
  73             dataL[i] = value;
  74         }
  75     }
  76 
  77 
  78 
  79     public int fooInstanceII(int x) {
  80         return x;
  81     }
  82 
  83     public static int fooStaticII(int x) {
  84         return x;
  85     }
  86 
  87     public int fooInstanceIL(Integer v) {
  88         return v;
  89     }
  90 
  91     public static int fooStaticIL(Integer v) {
  92         return v;
  93     }
  94 
  95     public Integer fooInstanceLL(Integer v) {
  96         return v;
  97     }
  98 
  99     public static Integer fooStaticLL(Integer v) {
 100         return v;
 101     }
 102 
 103     @Benchmark
 104     @OperationsPerInvocation(LIMIT)
 105     public void baselineII(Blackhole bh) {
 106         for (int i = 0; i < LIMIT; i++) {
 107             bh.consume(fooInstanceII(dataI[i]));
 108         }
 109     }
 110 
 111     @Benchmark
 112     @OperationsPerInvocation(LIMIT)
 113     public void baselineIL(Blackhole bh) {
 114         for (int i = 0; i < LIMIT; i++) {
 115             bh.consume(fooInstanceIL(dataL[i]));
 116         }
 117     }
 118 
 119     @Benchmark
 120     @OperationsPerInvocation(LIMIT)
 121     public void baselineLL(Blackhole bh) {
 122         for (int i = 0; i < LIMIT; i++) {
 123             bh.consume(fooInstanceLL(dataL[i]));
 124         }
 125     }
 126 
 127     public final FunctionII anonymII =
 128             new FunctionII() {
 129                 @Override
 130                 public int foo(int x) {
 131                     return x;
 132                 }
 133             };
 134 
 135     public final FunctionIL anonymIL =
 136             new FunctionIL() {
 137                 @Override
 138                 public int foo(Integer v) {
 139                     return v;
 140                 }
 141             };
 142 
 143     public final FunctionLL anonymLL =
 144             new FunctionLL() {
 145                 @Override
 146                 public Integer foo(Integer v) {
 147                     return v;
 148                 }
 149             };
 150 
 151 
 152     @Benchmark
 153     @OperationsPerInvocation(LIMIT)
 154     public void innerII(Blackhole bh) {
 155         processII(bh, anonymII);
 156     }
 157 
 158     @Benchmark
 159     @OperationsPerInvocation(LIMIT)
 160     public void innerIL(Blackhole bh) {
 161         processIL(bh, anonymIL);
 162     }
 163 
 164     @Benchmark
 165     @OperationsPerInvocation(LIMIT)
 166     public void innerLL(Blackhole bh) {
 167         processLL(bh, anonymLL);
 168     }
 169 
 170     public final FunctionII lambdaII =  x -> x;
 171 
 172     public final FunctionIL lambdaIL =  v -> v;
 173 
 174     public final FunctionLL lambdaLL =  v -> v;
 175 
 176 
 177     @Benchmark
 178     @OperationsPerInvocation(LIMIT)
 179     public void lambdaII(Blackhole bh) {
 180         processII(bh, lambdaII);
 181     }
 182 
 183     @Benchmark
 184     @OperationsPerInvocation(LIMIT)
 185     public void lambdaIL(Blackhole bh) {
 186         processIL(bh, lambdaIL);
 187     }
 188 
 189     @Benchmark
 190     @OperationsPerInvocation(LIMIT)
 191     public void lambdaLL(Blackhole bh) {
 192         processLL(bh, lambdaLL);
 193     }
 194 
 195 
 196 
 197     public final FunctionII mref_II2II  = Function1::fooStaticII;
 198     public final FunctionII mref_II2II_bound = this::fooInstanceII;
 199     public final FunctionIL mref_II2IL  = Function1::fooStaticII;
 200     public final FunctionIL mref_II2IL_bound = this::fooInstanceII;
 201     public final FunctionLL mref_II2LL  = Function1::fooStaticII;
 202     public final FunctionLL mref_II2LL_bound = this::fooInstanceII;
 203 
 204     public final FunctionII mref_IL2II  = Function1::fooStaticIL;
 205     public final FunctionII mref_IL2II_bound = this::fooInstanceIL;
 206     public final FunctionIL mref_IL2IL  = Function1::fooStaticIL;
 207     public final FunctionIL mref_IL2IL_bound = this::fooInstanceIL;
 208     public final FunctionLL mref_IL2LL  = Function1::fooStaticIL;
 209     public final FunctionLL mref_IL2LL_bound = this::fooInstanceIL;
 210 
 211     public final FunctionII mref_LL2II  = Function1::fooStaticLL;
 212     public final FunctionII mref_LL2II_bound = this::fooInstanceLL;
 213     public final FunctionIL mref_LL2IL  = Function1::fooStaticLL;
 214     public final FunctionIL mref_LL2IL_bound = this::fooInstanceLL;
 215     public final FunctionLL mref_LL2LL  = Function1::fooStaticLL;
 216     public final FunctionLL mref_LL2LL_bound = this::fooInstanceLL;
 217 
 218 
 219     // mref naming
 220     // sig1_sig2 where:
 221     // sig1 - signature of the method referenced by method ref
 222     // sig2 - FuntionalInterface signature
 223 
 224     @Benchmark
 225     @OperationsPerInvocation(LIMIT)
 226     public void mrefII_II(Blackhole bh) {
 227         processII(bh, mref_II2II);
 228     }
 229 
 230     @Benchmark
 231     @OperationsPerInvocation(LIMIT)
 232     public void mref_bndII_II(Blackhole bh) {
 233         processII(bh, mref_II2II_bound);
 234     }
 235 
 236     @Benchmark
 237     @OperationsPerInvocation(LIMIT)
 238     public void mrefII_IL(Blackhole bh) {
 239         processIL(bh, mref_II2IL);
 240     }
 241 
 242     @Benchmark
 243     @OperationsPerInvocation(LIMIT)
 244     public void mref_bndII_IL(Blackhole bh) {
 245         processIL(bh, mref_II2IL_bound);
 246     }
 247 
 248     @Benchmark
 249     @OperationsPerInvocation(LIMIT)
 250     public void mrefII_LL(Blackhole bh) {
 251         processLL(bh, mref_II2LL);
 252     }
 253 
 254     @Benchmark
 255     @OperationsPerInvocation(LIMIT)
 256     public void mref_bndII_LL(Blackhole bh) {
 257         processLL(bh, mref_II2LL_bound);
 258     }
 259 
 260     @Benchmark
 261     @OperationsPerInvocation(LIMIT)
 262     public void mrefIL_II(Blackhole bh) {
 263         processII(bh, mref_IL2II);
 264     }
 265 
 266     @Benchmark
 267     @OperationsPerInvocation(LIMIT)
 268     public void mref_bndIL_II(Blackhole bh) {
 269         processII(bh, mref_IL2II_bound);
 270     }
 271 
 272     @Benchmark
 273     @OperationsPerInvocation(LIMIT)
 274     public void mrefIL_IL(Blackhole bh) {
 275         processIL(bh, mref_IL2IL);
 276     }
 277 
 278     @Benchmark
 279     @OperationsPerInvocation(LIMIT)
 280     public void mref_bndIL_IL(Blackhole bh) {
 281         processIL(bh, mref_IL2IL_bound);
 282     }
 283 
 284     @Benchmark
 285     @OperationsPerInvocation(LIMIT)
 286     public void mrefIL_LL(Blackhole bh) {
 287         processLL(bh, mref_IL2LL);
 288     }
 289 
 290     @Benchmark
 291     @OperationsPerInvocation(LIMIT)
 292     public void mref_bndIL_LL(Blackhole bh) {
 293         processLL(bh, mref_IL2LL_bound);
 294     }
 295 
 296     @Benchmark
 297     @OperationsPerInvocation(LIMIT)
 298     public void mrefLL_II(Blackhole bh) {
 299         processII(bh, mref_LL2II);
 300     }
 301 
 302     @Benchmark
 303     @OperationsPerInvocation(LIMIT)
 304     public void mref_bndLL_II(Blackhole bh) {
 305         processII(bh, mref_LL2II_bound);
 306     }
 307 
 308     @Benchmark
 309     @OperationsPerInvocation(LIMIT)
 310     public void mrefLL_IL(Blackhole bh) {
 311         processIL(bh, mref_LL2IL);
 312     }
 313 
 314     @Benchmark
 315     @OperationsPerInvocation(LIMIT)
 316     public void mref_bndLL_IL(Blackhole bh) {
 317         processIL(bh, mref_LL2IL_bound);
 318     }
 319 
 320     @Benchmark
 321     @OperationsPerInvocation(LIMIT)
 322     public void mrefLL_LL(Blackhole bh) {
 323         processLL(bh, mref_LL2LL);
 324     }
 325 
 326     @Benchmark
 327     @OperationsPerInvocation(LIMIT)
 328     public void mref_bndLL_LL(Blackhole bh) {
 329         processLL(bh, mref_LL2LL_bound);
 330     }
 331 
 332 
 333     private void processII(Blackhole bh, FunctionII func) {
 334         for (int i = 0; i < LIMIT; i++) {
 335             bh.consume(func.foo(dataI[i]));
 336         }
 337     }
 338 
 339     private void processIL(Blackhole bh, FunctionIL func) {
 340         for (int i = 0; i < LIMIT; i++) {
 341             bh.consume(func.foo(dataL[i]));
 342         }
 343     }
 344 
 345     private void processLL(Blackhole bh, FunctionLL func) {
 346         for (int i = 0; i < LIMIT; i++) {
 347             bh.consume(func.foo(dataL[i]));
 348         }
 349     }
 350 
 351 }
 352