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.Mode;
  28 import org.openjdk.jmh.annotations.OutputTimeUnit;
  29 import org.openjdk.jmh.annotations.Scope;
  30 import org.openjdk.jmh.annotations.State;
  31 
  32 import java.util.concurrent.TimeUnit;
  33 
  34 /**
  35  * evaluates invocation costs.
  36  *
  37  * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
  38  */
  39 @BenchmarkMode(Mode.AverageTime)
  40 @OutputTimeUnit(TimeUnit.NANOSECONDS)
  41 @State(Scope.Thread)
  42 public class Function0 {
  43 
  44     public interface FunctionI {
  45         int foo();
  46     }
  47 
  48     public interface FunctionL {
  49         Integer foo();
  50     }
  51 
  52     private static int valueI = 40002; // bypass Integer.cache
  53     private static Integer valueL = Integer.valueOf(valueI);
  54 
  55     public int fooInstanceI() {
  56         return valueI;
  57     }
  58 
  59     public static int fooStaticI() {
  60         return valueI;
  61     }
  62 
  63     public Integer fooInstanceL() {
  64         return valueL;
  65     }
  66 
  67     public static Integer fooStaticL() {
  68         return valueL;
  69     }
  70 
  71     @Benchmark
  72     public int baselineI() {
  73         return fooInstanceI();
  74     }
  75 
  76     @Benchmark
  77     public Integer baselineL() {
  78         return fooInstanceL();
  79     }
  80 
  81     public final FunctionI anonymI =
  82             new FunctionI() {
  83                 @Override
  84                 public int foo() {
  85                     return valueI;
  86                 }
  87             };
  88 
  89     public final FunctionL anonymL =
  90             new FunctionL() {
  91                 @Override
  92                 public Integer foo() {
  93                     return valueL;
  94                 }
  95             };
  96 
  97     @Benchmark
  98     public int innerI() {
  99         return anonymI.foo();
 100     }
 101 
 102     @Benchmark
 103     public Integer innerL() {
 104         return anonymL.foo();
 105     }
 106 
 107     public final FunctionI lambdaI = () -> valueI;
 108 
 109     public final FunctionL lambdaL = () -> valueL;
 110 
 111     @Benchmark
 112     public int lambdaI() {
 113         return lambdaI.foo();
 114     }
 115 
 116     @Benchmark
 117     public Integer lambdaL() {
 118         return lambdaL.foo();
 119     }
 120 
 121     public final FunctionI mref_I2I  = Function0::fooStaticI;
 122     public final FunctionI mref_I2I_bound = this::fooInstanceI;
 123 
 124     public final FunctionL mref_I2L  = Function0::fooStaticI;
 125     public final FunctionL mref_I2L_bound = this::fooInstanceI;
 126 
 127     public final FunctionI mref_L2I  = Function0::fooStaticL;
 128     public final FunctionI mref_L2I_bound = this::fooInstanceL;
 129 
 130     public final FunctionL mref_L2L  = Function0::fooStaticL;
 131     public final FunctionL mref_L2L_bound = this::fooInstanceL;
 132 
 133     // mref naming
 134     // sig1_sig2 where:
 135     // sig1 - signature of the method referenced by method ref
 136     // sig2 - FuntionalInterface signature
 137 
 138     @Benchmark
 139     public int mrefI_I() {
 140         return mref_I2I.foo();
 141     }
 142 
 143     @Benchmark
 144     public int mref_bndI_I() {
 145         return mref_I2I_bound.foo();
 146     }
 147 
 148     @Benchmark
 149     public Integer mrefI_L() {
 150         return mref_I2L.foo();
 151     }
 152 
 153     @Benchmark
 154     public Integer mref_bndI_L() {
 155         return mref_I2L_bound.foo();
 156     }
 157 
 158     @Benchmark
 159     public int mrefL_I() {
 160         return mref_L2I.foo();
 161     }
 162 
 163     @Benchmark
 164     public int mref_bndL_I() {
 165         return mref_L2I_bound.foo();
 166     }
 167 
 168     @Benchmark
 169     public Integer mrefL_L() {
 170         return mref_L2L.foo();
 171     }
 172 
 173     @Benchmark
 174     public Integer mref_bndL_L() {
 175         return mref_L2L_bound.foo();
 176     }
 177 
 178 
 179 }
 180