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