View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.perf.jmh;
18  
19  import org.apache.logging.log4j.core.impl.ReflectiveCallerClassUtility;
20  import org.apache.logging.log4j.message.Message;
21  import org.apache.logging.log4j.message.StringFormattedMessage;
22  import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
23  import org.openjdk.jmh.annotations.Level;
24  import org.openjdk.jmh.annotations.Scope;
25  import org.openjdk.jmh.annotations.Setup;
26  import org.openjdk.jmh.annotations.State;
27  import org.openjdk.jmh.logic.BlackHole;
28  import sun.reflect.Reflection;
29  
30  import java.lang.reflect.Constructor;
31  import java.lang.reflect.InvocationTargetException;
32  import java.util.Random;
33  
34  /**
35   * <p>Benchmarks the different ways the caller class can be obtained.
36   * To run this in sampling mode (latency test):</p>
37   * <pre>
38   *     java -jar microbenchmarks.jar ".*ReflectionBenchmark.*" -i 5 -f 1 -wi 5 -bm sample -tu ns
39   * </pre>
40   * <p>To run this in throughput testing mode:</p>
41   * <pre>
42   *     java -jar microbenchmarks.jar ".*ReflectionBenchmark.*" -i 5 -f 1 -wi 5 -bm Throughput -tu ms
43   * </pre>
44   */
45  public class ReflectionBenchmark {
46  
47      @State(Scope.Thread)
48      public static class RandomInteger {
49  
50          private final Random r = new Random();
51  
52          int random;
53  
54          @Setup(Level.Iteration)
55          public void setup() {
56              random = r.nextInt();
57          }
58      }
59  
60      @GenerateMicroBenchmark
61      public void testBaseline(final BlackHole bh) {
62      }
63  
64      @GenerateMicroBenchmark
65      public String getCallerClassNameFromStackTrace(final BlackHole bh) {
66          return new Throwable().getStackTrace()[3].getClassName();
67      }
68  
69      @GenerateMicroBenchmark
70      public String getCallerClassNameReflectively(final BlackHole bh) {
71          return ReflectiveCallerClassUtility.getCaller(3).getName();
72      }
73  
74      @GenerateMicroBenchmark
75      public String getCallerClassNameSunReflection(final BlackHole bh) {
76          return Reflection.getCallerClass(3).getName();
77      }
78  
79      @GenerateMicroBenchmark
80      public Class<?> getStackTraceClassForClassName() throws ClassNotFoundException {
81          return Class.forName(new Throwable().getStackTrace()[3].getClassName());
82      }
83  
84      @GenerateMicroBenchmark
85      public Class<?> getReflectiveCallerClassUtility(final BlackHole bh) {
86          return ReflectiveCallerClassUtility.getCaller(3);
87      }
88  
89      @GenerateMicroBenchmark
90      public Class<?> getDirectSunReflection(final BlackHole bh) {
91          return Reflection.getCallerClass(3);
92      }
93  
94      @GenerateMicroBenchmark
95      public Message getMessageUsingNew(final RandomInteger rng) {
96          return new StringFormattedMessage("Hello %i", rng.random);
97      }
98  
99      @GenerateMicroBenchmark
100     public Message getMessageUsingReflection(final RandomInteger rng)
101         throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
102         final Constructor<? extends Message> constructor = StringFormattedMessage.class.getConstructor(String.class,
103             Object[].class);
104         return constructor.newInstance("Hello %i", new Object[]{rng.random});
105     }
106 }