|
1 /* |
|
2 * Copyright (c) 2014, 2019, 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.java.lang.reflect.proxy; |
|
24 |
|
25 import java.util.List; |
|
26 |
|
27 import org.openjdk.jmh.annotations.Benchmark; |
|
28 import org.openjdk.jmh.annotations.BenchmarkMode; |
|
29 import org.openjdk.jmh.annotations.CompilerControl; |
|
30 import org.openjdk.jmh.annotations.Fork; |
|
31 import org.openjdk.jmh.annotations.Measurement; |
|
32 import org.openjdk.jmh.annotations.Mode; |
|
33 import org.openjdk.jmh.annotations.OutputTimeUnit; |
|
34 import org.openjdk.jmh.annotations.Scope; |
|
35 import org.openjdk.jmh.annotations.Setup; |
|
36 import org.openjdk.jmh.annotations.State; |
|
37 import org.openjdk.jmh.annotations.Warmup; |
|
38 |
|
39 import org.openjdk.jmh.infra.Blackhole; |
|
40 |
|
41 import java.lang.reflect.InvocationHandler; |
|
42 import java.lang.reflect.InvocationTargetException; |
|
43 import java.lang.reflect.Method; |
|
44 import java.lang.reflect.Modifier; |
|
45 import java.util.concurrent.TimeUnit; |
|
46 |
|
47 /** |
|
48 * Benchmark measuring java.lang.reflect.ProxyGenerator.generateProxyClass. |
|
49 * It bypasses the cache of proxies to measure the time to construct a proxy. |
|
50 */ |
|
51 @Warmup(iterations = 5) |
|
52 @Measurement(iterations = 10) |
|
53 @Fork(value = 1) |
|
54 @BenchmarkMode(Mode.AverageTime) |
|
55 @OutputTimeUnit(TimeUnit.NANOSECONDS) |
|
56 @State(Scope.Thread) |
|
57 public class ProxyPerf { |
|
58 |
|
59 /** |
|
60 * Sample results from a Dell T7610. |
|
61 * Benchmark Mode Cnt Score Error Units |
|
62 * ProxyPerf.genIntf_1 avgt 10 35325.428 +/- 780.459 ns/op |
|
63 * ProxyPerf.genIntf_1_V49 avgt 10 34309.423 +/- 727.188 ns/op |
|
64 * ProxyPerf.genStringsIntf_3 avgt 10 46600.366 +/- 663.812 ns/op |
|
65 * ProxyPerf.genStringsIntf_3_V49 avgt 10 45911.817 +/- 1598.536 ns/op |
|
66 * ProxyPerf.genZeroParams avgt 10 33245.048 +/- 437.988 ns/op |
|
67 * ProxyPerf.genZeroParams_V49 avgt 10 32954.254 +/- 1041.932 ns/op |
|
68 * ProxyPerf.getPrimsIntf_2 avgt 10 43987.819 +/- 837.443 ns/op |
|
69 * ProxyPerf.getPrimsIntf_2_V49 avgt 10 42863.462 +/- 1193.480 ns/op |
|
70 */ |
|
71 |
|
72 public interface Intf_1 { |
|
73 public Object mL(Object o); |
|
74 } |
|
75 |
|
76 public interface Intf_2 { |
|
77 public int m1I(int i); |
|
78 public long m2IJ(int i, long l); |
|
79 } |
|
80 |
|
81 public interface Intf_3 { |
|
82 public void mString(String s1); |
|
83 public String m2String(String s1); |
|
84 public String m2String(String s1, String s2); |
|
85 } |
|
86 |
|
87 private InvocationHandler handler; |
|
88 private ClassLoader classloader; |
|
89 private Method proxyGen; |
|
90 private Method proxyGenV49; |
|
91 |
|
92 @Setup |
|
93 public void setup() { |
|
94 try { |
|
95 handler = (Object proxy, Method method, Object[] args) -> null; |
|
96 classloader = ClassLoader.getSystemClassLoader(); |
|
97 Class<?> proxyGenClass = Class.forName("java.lang.reflect.ProxyGenerator"); |
|
98 proxyGen = proxyGenClass.getDeclaredMethod("generateProxyClass", |
|
99 ClassLoader.class, String.class, java.util.List.class, int.class); |
|
100 proxyGen.setAccessible(true); |
|
101 |
|
102 // Init access to the old Proxy generator |
|
103 Class<?> proxyGenClassV49 = Class.forName("java.lang.reflect.ProxyGenerator_v49"); |
|
104 proxyGenV49 = proxyGenClassV49.getDeclaredMethod("generateProxyClass", |
|
105 String.class, java.util.List.class, int.class); |
|
106 proxyGenV49.setAccessible(true); |
|
107 |
|
108 } catch (Exception ex) { |
|
109 ex.printStackTrace(); |
|
110 throw new RuntimeException("ProxyClass setup fails", ex); |
|
111 } |
|
112 } |
|
113 |
|
114 @Benchmark |
|
115 public void genZeroParams(Blackhole bh) throws Exception { |
|
116 List<Class<?>> interfaces = List.of(Runnable.class); |
|
117 bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1)); |
|
118 } |
|
119 |
|
120 @Benchmark |
|
121 public void genIntf_1(Blackhole bh) throws Exception { |
|
122 List<Class<?>> interfaces = List.of(Intf_1.class); |
|
123 bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1)); |
|
124 } |
|
125 |
|
126 @Benchmark |
|
127 public void getPrimsIntf_2(Blackhole bh) throws Exception { |
|
128 List<Class<?>> interfaces = List.of(Intf_2.class); |
|
129 bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1)); |
|
130 } |
|
131 @Benchmark |
|
132 public void genStringsIntf_3(Blackhole bh) throws Exception { |
|
133 List<Class<?>> interfaces = List.of(Intf_3.class); |
|
134 bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1)); |
|
135 } |
|
136 |
|
137 // Generate using the V49inal generator for comparison |
|
138 |
|
139 @Benchmark |
|
140 public void genZeroParams_V49(Blackhole bh) throws Exception { |
|
141 List<Class<?>> interfaces = List.of(Runnable.class); |
|
142 bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1)); |
|
143 } |
|
144 |
|
145 @Benchmark |
|
146 public void genIntf_1_V49(Blackhole bh) throws Exception { |
|
147 List<Class<?>> interfaces = List.of(Intf_1.class); |
|
148 bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1)); |
|
149 } |
|
150 |
|
151 @Benchmark |
|
152 public void getPrimsIntf_2_V49(Blackhole bh) throws Exception { |
|
153 List<Class<?>> interfaces = List.of(Intf_2.class); |
|
154 bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1)); |
|
155 } |
|
156 @Benchmark |
|
157 public void genStringsIntf_3_V49(Blackhole bh) throws Exception { |
|
158 List<Class<?>> interfaces = List.of(Intf_3.class); |
|
159 bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1)); |
|
160 } |
|
161 |
|
162 } |