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