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