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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.openjdk.bench.vm.lambda.invoke; 26 27 import org.openjdk.jmh.annotations.Benchmark; 28 import org.openjdk.jmh.annotations.BenchmarkMode; 29 import org.openjdk.jmh.annotations.Level; 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.infra.Blackhole; 37 38 import java.util.concurrent.ThreadLocalRandom; 39 import java.util.concurrent.TimeUnit; 40 41 /** 42 * evaluates invocation costs. 43 * 44 * @author Sergey Kuksenko (sergey.kuksenko@oracle.com) 45 */ 46 @BenchmarkMode(Mode.AverageTime) 47 @OutputTimeUnit(TimeUnit.NANOSECONDS) 48 @State(Scope.Thread) 49 public class Function1 { 50 51 public interface FunctionII { 52 int foo(int x); 53 } 54 55 public interface FunctionIL { 56 int foo(Integer x); 57 } 58 59 public interface FunctionLL { 60 Integer foo(Integer x); 61 } 62 63 private static final int LIMIT = 1024; 64 65 private final int[] dataI = new int[LIMIT + 1]; 66 private final Integer[] dataL = new Integer[LIMIT + 1]; 67 68 @Setup(Level.Iteration) 69 public void setup() { 70 for (int i = 0; i < dataI.length; i++) { 71 int value = ThreadLocalRandom.current().nextInt(10001,420000); // bypass Integer.cache 72 dataI[i] = value; 73 dataL[i] = value; 74 } 75 } 76 77 78 79 public int fooInstanceII(int x) { 80 return x; 81 } 82 83 public static int fooStaticII(int x) { 84 return x; 85 } 86 87 public int fooInstanceIL(Integer v) { 88 return v; 89 } 90 91 public static int fooStaticIL(Integer v) { 92 return v; 93 } 94 95 public Integer fooInstanceLL(Integer v) { 96 return v; 97 } 98 99 public static Integer fooStaticLL(Integer v) { 100 return v; 101 } 102 103 @Benchmark 104 @OperationsPerInvocation(LIMIT) 105 public void baselineII(Blackhole bh) { 106 for (int i = 0; i < LIMIT; i++) { 107 bh.consume(fooInstanceII(dataI[i])); 108 } 109 } 110 111 @Benchmark 112 @OperationsPerInvocation(LIMIT) 113 public void baselineIL(Blackhole bh) { 114 for (int i = 0; i < LIMIT; i++) { 115 bh.consume(fooInstanceIL(dataL[i])); 116 } 117 } 118 119 @Benchmark 120 @OperationsPerInvocation(LIMIT) 121 public void baselineLL(Blackhole bh) { 122 for (int i = 0; i < LIMIT; i++) { 123 bh.consume(fooInstanceLL(dataL[i])); 124 } 125 } 126 127 public final FunctionII anonymII = 128 new FunctionII() { 129 @Override 130 public int foo(int x) { 131 return x; 132 } 133 }; 134 135 public final FunctionIL anonymIL = 136 new FunctionIL() { 137 @Override 138 public int foo(Integer v) { 139 return v; 140 } 141 }; 142 143 public final FunctionLL anonymLL = 144 new FunctionLL() { 145 @Override 146 public Integer foo(Integer v) { 147 return v; 148 } 149 }; 150 151 152 @Benchmark 153 @OperationsPerInvocation(LIMIT) 154 public void innerII(Blackhole bh) { 155 processII(bh, anonymII); 156 } 157 158 @Benchmark 159 @OperationsPerInvocation(LIMIT) 160 public void innerIL(Blackhole bh) { 161 processIL(bh, anonymIL); 162 } 163 164 @Benchmark 165 @OperationsPerInvocation(LIMIT) 166 public void innerLL(Blackhole bh) { 167 processLL(bh, anonymLL); 168 } 169 170 public final FunctionII lambdaII = x -> x; 171 172 public final FunctionIL lambdaIL = v -> v; 173 174 public final FunctionLL lambdaLL = v -> v; 175 176 177 @Benchmark 178 @OperationsPerInvocation(LIMIT) 179 public void lambdaII(Blackhole bh) { 180 processII(bh, lambdaII); 181 } 182 183 @Benchmark 184 @OperationsPerInvocation(LIMIT) 185 public void lambdaIL(Blackhole bh) { 186 processIL(bh, lambdaIL); 187 } 188 189 @Benchmark 190 @OperationsPerInvocation(LIMIT) 191 public void lambdaLL(Blackhole bh) { 192 processLL(bh, lambdaLL); 193 } 194 195 196 197 public final FunctionII mref_II2II = Function1::fooStaticII; 198 public final FunctionII mref_II2II_bound = this::fooInstanceII; 199 public final FunctionIL mref_II2IL = Function1::fooStaticII; 200 public final FunctionIL mref_II2IL_bound = this::fooInstanceII; 201 public final FunctionLL mref_II2LL = Function1::fooStaticII; 202 public final FunctionLL mref_II2LL_bound = this::fooInstanceII; 203 204 public final FunctionII mref_IL2II = Function1::fooStaticIL; 205 public final FunctionII mref_IL2II_bound = this::fooInstanceIL; 206 public final FunctionIL mref_IL2IL = Function1::fooStaticIL; 207 public final FunctionIL mref_IL2IL_bound = this::fooInstanceIL; 208 public final FunctionLL mref_IL2LL = Function1::fooStaticIL; 209 public final FunctionLL mref_IL2LL_bound = this::fooInstanceIL; 210 211 public final FunctionII mref_LL2II = Function1::fooStaticLL; 212 public final FunctionII mref_LL2II_bound = this::fooInstanceLL; 213 public final FunctionIL mref_LL2IL = Function1::fooStaticLL; 214 public final FunctionIL mref_LL2IL_bound = this::fooInstanceLL; 215 public final FunctionLL mref_LL2LL = Function1::fooStaticLL; 216 public final FunctionLL mref_LL2LL_bound = this::fooInstanceLL; 217 218 219 // mref naming 220 // sig1_sig2 where: 221 // sig1 - signature of the method referenced by method ref 222 // sig2 - FuntionalInterface signature 223 224 @Benchmark 225 @OperationsPerInvocation(LIMIT) 226 public void mrefII_II(Blackhole bh) { 227 processII(bh, mref_II2II); 228 } 229 230 @Benchmark 231 @OperationsPerInvocation(LIMIT) 232 public void mref_bndII_II(Blackhole bh) { 233 processII(bh, mref_II2II_bound); 234 } 235 236 @Benchmark 237 @OperationsPerInvocation(LIMIT) 238 public void mrefII_IL(Blackhole bh) { 239 processIL(bh, mref_II2IL); 240 } 241 242 @Benchmark 243 @OperationsPerInvocation(LIMIT) 244 public void mref_bndII_IL(Blackhole bh) { 245 processIL(bh, mref_II2IL_bound); 246 } 247 248 @Benchmark 249 @OperationsPerInvocation(LIMIT) 250 public void mrefII_LL(Blackhole bh) { 251 processLL(bh, mref_II2LL); 252 } 253 254 @Benchmark 255 @OperationsPerInvocation(LIMIT) 256 public void mref_bndII_LL(Blackhole bh) { 257 processLL(bh, mref_II2LL_bound); 258 } 259 260 @Benchmark 261 @OperationsPerInvocation(LIMIT) 262 public void mrefIL_II(Blackhole bh) { 263 processII(bh, mref_IL2II); 264 } 265 266 @Benchmark 267 @OperationsPerInvocation(LIMIT) 268 public void mref_bndIL_II(Blackhole bh) { 269 processII(bh, mref_IL2II_bound); 270 } 271 272 @Benchmark 273 @OperationsPerInvocation(LIMIT) 274 public void mrefIL_IL(Blackhole bh) { 275 processIL(bh, mref_IL2IL); 276 } 277 278 @Benchmark 279 @OperationsPerInvocation(LIMIT) 280 public void mref_bndIL_IL(Blackhole bh) { 281 processIL(bh, mref_IL2IL_bound); 282 } 283 284 @Benchmark 285 @OperationsPerInvocation(LIMIT) 286 public void mrefIL_LL(Blackhole bh) { 287 processLL(bh, mref_IL2LL); 288 } 289 290 @Benchmark 291 @OperationsPerInvocation(LIMIT) 292 public void mref_bndIL_LL(Blackhole bh) { 293 processLL(bh, mref_IL2LL_bound); 294 } 295 296 @Benchmark 297 @OperationsPerInvocation(LIMIT) 298 public void mrefLL_II(Blackhole bh) { 299 processII(bh, mref_LL2II); 300 } 301 302 @Benchmark 303 @OperationsPerInvocation(LIMIT) 304 public void mref_bndLL_II(Blackhole bh) { 305 processII(bh, mref_LL2II_bound); 306 } 307 308 @Benchmark 309 @OperationsPerInvocation(LIMIT) 310 public void mrefLL_IL(Blackhole bh) { 311 processIL(bh, mref_LL2IL); 312 } 313 314 @Benchmark 315 @OperationsPerInvocation(LIMIT) 316 public void mref_bndLL_IL(Blackhole bh) { 317 processIL(bh, mref_LL2IL_bound); 318 } 319 320 @Benchmark 321 @OperationsPerInvocation(LIMIT) 322 public void mrefLL_LL(Blackhole bh) { 323 processLL(bh, mref_LL2LL); 324 } 325 326 @Benchmark 327 @OperationsPerInvocation(LIMIT) 328 public void mref_bndLL_LL(Blackhole bh) { 329 processLL(bh, mref_LL2LL_bound); 330 } 331 332 333 private void processII(Blackhole bh, FunctionII func) { 334 for (int i = 0; i < LIMIT; i++) { 335 bh.consume(func.foo(dataI[i])); 336 } 337 } 338 339 private void processIL(Blackhole bh, FunctionIL func) { 340 for (int i = 0; i < LIMIT; i++) { 341 bh.consume(func.foo(dataL[i])); 342 } 343 } 344 345 private void processLL(Blackhole bh, FunctionLL func) { 346 for (int i = 0; i < LIMIT; i++) { 347 bh.consume(func.foo(dataL[i])); 348 } 349 } 350 351 } 352