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