1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.libcore.regression;
18 
19 import android.perftests.utils.BenchmarkState;
20 import android.perftests.utils.PerfStatusReporter;
21 import android.test.suitebuilder.annotation.LargeTest;
22 
23 import androidx.test.runner.AndroidJUnit4;
24 
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 
29 import java.lang.reflect.Constructor;
30 import java.lang.reflect.Field;
31 import java.lang.reflect.Method;
32 
33 @RunWith(AndroidJUnit4.class)
34 @LargeTest
35 public class ReflectionPerfTest {
36     @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
37 
38     @Test
timeObject_getClass()39     public void timeObject_getClass() throws Exception {
40         C c = new C();
41         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
42         while (state.keepRunning()) {
43             c.getClass();
44         }
45     }
46 
47     @Test
timeClass_getField()48     public void timeClass_getField() throws Exception {
49         Class<?> klass = C.class;
50         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
51         while (state.keepRunning()) {
52             klass.getField("f");
53         }
54     }
55 
56     @Test
timeClass_getDeclaredField()57     public void timeClass_getDeclaredField() throws Exception {
58         Class<?> klass = C.class;
59         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
60         while (state.keepRunning()) {
61             klass.getDeclaredField("f");
62         }
63     }
64 
65     @Test
timeClass_getConstructor()66     public void timeClass_getConstructor() throws Exception {
67         Class<?> klass = C.class;
68         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
69         while (state.keepRunning()) {
70             klass.getConstructor();
71         }
72     }
73 
74     @Test
timeClass_newInstance()75     public void timeClass_newInstance() throws Exception {
76         Class<?> klass = C.class;
77         Constructor constructor = klass.getConstructor();
78         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
79         while (state.keepRunning()) {
80             constructor.newInstance();
81         }
82     }
83 
84     @Test
timeClass_getMethod()85     public void timeClass_getMethod() throws Exception {
86         Class<?> klass = C.class;
87         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
88         while (state.keepRunning()) {
89             klass.getMethod("m");
90         }
91     }
92 
93     @Test
timeClass_getDeclaredMethod()94     public void timeClass_getDeclaredMethod() throws Exception {
95         Class<?> klass = C.class;
96         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
97         while (state.keepRunning()) {
98             klass.getDeclaredMethod("m");
99         }
100     }
101 
102     @Test
timeField_setInt()103     public void timeField_setInt() throws Exception {
104         Class<?> klass = C.class;
105         Field f = klass.getDeclaredField("f");
106         C instance = new C();
107         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
108         while (state.keepRunning()) {
109             f.setInt(instance, 1);
110         }
111     }
112 
113     @Test
timeField_getInt()114     public void timeField_getInt() throws Exception {
115         Class<?> klass = C.class;
116         Field f = klass.getDeclaredField("f");
117         C instance = new C();
118         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
119         while (state.keepRunning()) {
120             f.getInt(instance);
121         }
122     }
123 
124     @Test
timeMethod_invokeV()125     public void timeMethod_invokeV() throws Exception {
126         Class<?> klass = C.class;
127         Method m = klass.getDeclaredMethod("m");
128         C instance = new C();
129         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
130         while (state.keepRunning()) {
131             m.invoke(instance);
132         }
133     }
134 
135     @Test
timeMethod_invokeStaticV()136     public void timeMethod_invokeStaticV() throws Exception {
137         Class<?> klass = C.class;
138         Method m = klass.getDeclaredMethod("sm");
139         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
140         while (state.keepRunning()) {
141             m.invoke(null);
142         }
143     }
144 
145     @Test
timeMethod_invokeI()146     public void timeMethod_invokeI() throws Exception {
147         Class<?> klass = C.class;
148         Method m = klass.getDeclaredMethod("setField", int.class);
149         C instance = new C();
150         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
151         while (state.keepRunning()) {
152             m.invoke(instance, 1);
153         }
154     }
155 
156     @Test
timeMethod_invokePreBoxedI()157     public void timeMethod_invokePreBoxedI() throws Exception {
158         Class<?> klass = C.class;
159         Method m = klass.getDeclaredMethod("setField", int.class);
160         C instance = new C();
161         Integer one = Integer.valueOf(1);
162         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
163         while (state.keepRunning()) {
164             m.invoke(instance, one);
165         }
166     }
167 
168     @Test
timeMethod_invokeStaticI()169     public void timeMethod_invokeStaticI() throws Exception {
170         Class<?> klass = C.class;
171         Method m = klass.getDeclaredMethod("setStaticField", int.class);
172         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
173         while (state.keepRunning()) {
174             m.invoke(null, 1);
175         }
176     }
177 
178     @Test
timeMethod_invokeStaticPreBoxedI()179     public void timeMethod_invokeStaticPreBoxedI() throws Exception {
180         Class<?> klass = C.class;
181         Method m = klass.getDeclaredMethod("setStaticField", int.class);
182         Integer one = Integer.valueOf(1);
183         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
184         while (state.keepRunning()) {
185             m.invoke(null, one);
186         }
187     }
188 
189     @Test
timeRegularMethodInvocation()190     public void timeRegularMethodInvocation() throws Exception {
191         C instance = new C();
192         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
193         while (state.keepRunning()) {
194             instance.setField(1);
195         }
196     }
197 
198     @Test
timeRegularConstructor()199     public void timeRegularConstructor() throws Exception {
200         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
201         while (state.keepRunning()) {
202             new C();
203         }
204     }
205 
206     @Test
timeClass_classNewInstance()207     public void timeClass_classNewInstance() throws Exception {
208         Class<?> klass = C.class;
209         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
210         while (state.keepRunning()) {
211             klass.newInstance();
212         }
213     }
214 
215     @Test
timeClass_isInstance()216     public void timeClass_isInstance() throws Exception {
217         D d = new D();
218         Class<?> klass = IC.class;
219         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
220         while (state.keepRunning()) {
221             klass.isInstance(d);
222         }
223     }
224 
225     @Test
timeGetInstanceField()226     public void timeGetInstanceField() throws Exception {
227         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
228         while (state.keepRunning()) {
229             // TODO: Write a test script that generates both the classes we're
230             // reflecting on and the test case for each of its fields.
231             R.class.getField("mTextAppearanceLargePopupMenu");
232         }
233     }
234 
235     @Test
timeGetStaticField()236     public void timeGetStaticField() throws Exception {
237         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
238         while (state.keepRunning()) {
239             R.class.getField("WEEK_NUMBER_COLOR");
240         }
241     }
242 
243     @Test
timeGetInterfaceStaticField()244     public void timeGetInterfaceStaticField() throws Exception {
245         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
246         while (state.keepRunning()) {
247             F.class.getField("SF");
248         }
249     }
250 
251     @Test
timeGetSuperClassField()252     public void timeGetSuperClassField() throws Exception {
253         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
254         while (state.keepRunning()) {
255             G.class.getField("f");
256         }
257     }
258 
259     public static class C {
260         public static int sf = 0;
261         public int f = 0;
262 
C()263         public C() {
264             // A non-empty constructor so we don't get optimized away.
265             f = 1;
266         }
267 
m()268         public void m() {}
269 
sm()270         public static void sm() {}
271 
setField(int value)272         public void setField(int value) {
273             f = value;
274         }
275 
setStaticField(int value)276         public static void setStaticField(int value) {
277             sf = value;
278         }
279     }
280 
281     interface IA {}
282 
283     interface IB extends IA {}
284 
285     interface IC extends IB {
286         int SF = 0;
287     }
288 
289     class D implements IC {}
290 
291     class E extends D {}
292 
293     class F extends E implements IB {}
294 
295     class G extends C {}
296 }
297