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     @SuppressWarnings("initialization")
203     public final FunctionII mref_II2II_bound = this::fooInstanceII;
204     public final FunctionIL mref_II2IL  = Function1::fooStaticII;
205     @SuppressWarnings("initialization")
206     public final FunctionIL mref_II2IL_bound = this::fooInstanceII;
207     public final FunctionLL mref_II2LL  = Function1::fooStaticII;
208     @SuppressWarnings("initialization")
209     public final FunctionLL mref_II2LL_bound = this::fooInstanceII;
210 
211     public final FunctionII mref_IL2II  = Function1::fooStaticIL;
212     @SuppressWarnings("initialization")
213     public final FunctionII mref_IL2II_bound = this::fooInstanceIL;
214     public final FunctionIL mref_IL2IL  = Function1::fooStaticIL;
215     @SuppressWarnings("initialization")
216     public final FunctionIL mref_IL2IL_bound = this::fooInstanceIL;
217     public final FunctionLL mref_IL2LL  = Function1::fooStaticIL;
218     @SuppressWarnings("initialization")
219     public final FunctionLL mref_IL2LL_bound = this::fooInstanceIL;
220 
221     public final FunctionII mref_LL2II  = Function1::fooStaticLL;
222     @SuppressWarnings("initialization")
223     public final FunctionII mref_LL2II_bound = this::fooInstanceLL;
224     public final FunctionIL mref_LL2IL  = Function1::fooStaticLL;
225     @SuppressWarnings("initialization")
226     public final FunctionIL mref_LL2IL_bound = this::fooInstanceLL;
227     public final FunctionLL mref_LL2LL  = Function1::fooStaticLL;
228     @SuppressWarnings("initialization")
229     public final FunctionLL mref_LL2LL_bound = this::fooInstanceLL;
230 
231 
232     // mref naming
233     // sig1_sig2 where:
234     // sig1 - signature of the method referenced by method ref
235     // sig2 - FuntionalInterface signature
236 
237     @Benchmark
238     @OperationsPerInvocation(LIMIT)
239     public void mrefII_II(Blackhole bh) {
240         processII(bh, mref_II2II);
241     }
242 
243     @Benchmark
244     @OperationsPerInvocation(LIMIT)
245     public void mref_bndII_II(Blackhole bh) {
246         processII(bh, mref_II2II_bound);
247     }
248 
249     @Benchmark
250     @OperationsPerInvocation(LIMIT)
251     public void mrefII_IL(Blackhole bh) {
252         processIL(bh, mref_II2IL);
253     }
254 
255     @Benchmark
256     @OperationsPerInvocation(LIMIT)
257     public void mref_bndII_IL(Blackhole bh) {
258         processIL(bh, mref_II2IL_bound);
259     }
260 
261     @Benchmark
262     @OperationsPerInvocation(LIMIT)
263     public void mrefII_LL(Blackhole bh) {
264         processLL(bh, mref_II2LL);
265     }
266 
267     @Benchmark
268     @OperationsPerInvocation(LIMIT)
269     public void mref_bndII_LL(Blackhole bh) {
270         processLL(bh, mref_II2LL_bound);
271     }
272 
273     @Benchmark
274     @OperationsPerInvocation(LIMIT)
275     public void mrefIL_II(Blackhole bh) {
276         processII(bh, mref_IL2II);
277     }
278 
279     @Benchmark
280     @OperationsPerInvocation(LIMIT)
281     public void mref_bndIL_II(Blackhole bh) {
282         processII(bh, mref_IL2II_bound);
283     }
284 
285     @Benchmark
286     @OperationsPerInvocation(LIMIT)
287     public void mrefIL_IL(Blackhole bh) {
288         processIL(bh, mref_IL2IL);
289     }
290 
291     @Benchmark
292     @OperationsPerInvocation(LIMIT)
293     public void mref_bndIL_IL(Blackhole bh) {
294         processIL(bh, mref_IL2IL_bound);
295     }
296 
297     @Benchmark
298     @OperationsPerInvocation(LIMIT)
299     public void mrefIL_LL(Blackhole bh) {
300         processLL(bh, mref_IL2LL);
301     }
302 
303     @Benchmark
304     @OperationsPerInvocation(LIMIT)
305     public void mref_bndIL_LL(Blackhole bh) {
306         processLL(bh, mref_IL2LL_bound);
307     }
308 
309     @Benchmark
310     @OperationsPerInvocation(LIMIT)
311     public void mrefLL_II(Blackhole bh) {
312         processII(bh, mref_LL2II);
313     }
314 
315     @Benchmark
316     @OperationsPerInvocation(LIMIT)
317     public void mref_bndLL_II(Blackhole bh) {
318         processII(bh, mref_LL2II_bound);
319     }
320 
321     @Benchmark
322     @OperationsPerInvocation(LIMIT)
323     public void mrefLL_IL(Blackhole bh) {
324         processIL(bh, mref_LL2IL);
325     }
326 
327     @Benchmark
328     @OperationsPerInvocation(LIMIT)
329     public void mref_bndLL_IL(Blackhole bh) {
330         processIL(bh, mref_LL2IL_bound);
331     }
332 
333     @Benchmark
334     @OperationsPerInvocation(LIMIT)
335     public void mrefLL_LL(Blackhole bh) {
336         processLL(bh, mref_LL2LL);
337     }
338 
339     @Benchmark
340     @OperationsPerInvocation(LIMIT)
341     public void mref_bndLL_LL(Blackhole bh) {
342         processLL(bh, mref_LL2LL_bound);
343     }
344 
345 
346     private void processII(Blackhole bh, FunctionII func) {
347         for (int i = 0; i < LIMIT; i++) {
348             bh.consume(func.foo(dataI[i]));
349         }
350     }
351 
352     private void processIL(Blackhole bh, FunctionIL func) {
353         for (int i = 0; i < LIMIT; i++) {
354             bh.consume(func.foo(dataL[i]));
355         }
356     }
357 
358     private void processLL(Blackhole bh, FunctionLL func) {
359         for (int i = 0; i < LIMIT; i++) {
360             bh.consume(func.foo(dataL[i]));
361         }
362     }
363 
364 }
365