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 {
foo()45         int foo();
46     }
47 
48     public interface FunctionL {
foo()49         Integer foo();
50     }
51 
52     private static int valueI = 40002; // bypass Integer.cache
53     private static Integer valueL = Integer.valueOf(valueI);
54 
fooInstanceI()55     public int fooInstanceI() {
56         return valueI;
57     }
58 
fooStaticI()59     public static int fooStaticI() {
60         return valueI;
61     }
62 
fooInstanceL()63     public Integer fooInstanceL() {
64         return valueL;
65     }
66 
fooStaticL()67     public static Integer fooStaticL() {
68         return valueL;
69     }
70 
71     @Benchmark
baselineI()72     public int baselineI() {
73         return fooInstanceI();
74     }
75 
76     @Benchmark
baselineL()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
innerI()98     public int innerI() {
99         return anonymI.foo();
100     }
101 
102     @Benchmark
innerL()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
lambdaI()112     public int lambdaI() {
113         return lambdaI.foo();
114     }
115 
116     @Benchmark
lambdaL()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
mrefI_I()139     public int mrefI_I() {
140         return mref_I2I.foo();
141     }
142 
143     @Benchmark
mref_bndI_I()144     public int mref_bndI_I() {
145         return mref_I2I_bound.foo();
146     }
147 
148     @Benchmark
mrefI_L()149     public Integer mrefI_L() {
150         return mref_I2L.foo();
151     }
152 
153     @Benchmark
mref_bndI_L()154     public Integer mref_bndI_L() {
155         return mref_I2L_bound.foo();
156     }
157 
158     @Benchmark
mrefL_I()159     public int mrefL_I() {
160         return mref_L2I.foo();
161     }
162 
163     @Benchmark
mref_bndL_I()164     public int mref_bndL_I() {
165         return mref_L2I_bound.foo();
166     }
167 
168     @Benchmark
mrefL_L()169     public Integer mrefL_L() {
170         return mref_L2L.foo();
171     }
172 
173     @Benchmark
mref_bndL_L()174     public Integer mref_bndL_L() {
175         return mref_L2L_bound.foo();
176     }
177 
178 
179 }
180 
181