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.java.lang.invoke; 26 27 import org.openjdk.jmh.annotations.Benchmark; 28 import org.openjdk.jmh.annotations.BenchmarkMode; 29 import org.openjdk.jmh.annotations.Mode; 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 35 import java.lang.invoke.MethodHandle; 36 import java.lang.invoke.MethodHandles; 37 import java.util.concurrent.TimeUnit; 38 39 /** 40 * Benchmark assesses the performance of MethodHandles.arrayElementSetter 41 * 42 * @author Aleksey Shipilev (aleksey.shipilev@oracle.com) 43 */ 44 @BenchmarkMode(Mode.AverageTime) 45 @OutputTimeUnit(TimeUnit.NANOSECONDS) 46 @State(Scope.Thread) 47 public class MethodHandlesArrayElementSetter { 48 49 /** 50 * Implementation notes: 51 * - creating simple array, and accessing the middle element 52 * - might have done iteration over array, but that will measure pipelining effects instead 53 * - volatile modifier on array breaks the DCE, which would otherwise eliminate the array store 54 * - the array is not shared to prevent true sharing 55 * - the array is large enough to prevent false sharing 56 */ 57 58 private static final int SIZE = 1024; 59 private static final int POS = SIZE/2; 60 61 private static MethodHandle mh; 62 private volatile int[] array; 63 64 @Setup 65 public void setup() throws Throwable { 66 array = new int[SIZE]; 67 for (int i = 0; i < SIZE; i++) { 68 array[i] = i; 69 } 70 mh = MethodHandles.arrayElementSetter(int[].class); 71 } 72 73 @Benchmark 74 public MethodHandle testCreate() { 75 return MethodHandles.arrayElementSetter(int[].class); 76 } 77 78 @Benchmark 79 public void baselineRaw() { 80 access(array, POS, 1); 81 } 82 83 @Benchmark 84 public void testSetter() throws Throwable { 85 mh.invoke(array, POS, 1); 86 } 87 88 public void access(int[] array, int pos, int v) { 89 array[pos] = v; 90 } 91 92 }