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