You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/08/03 21:58:05 UTC

svn commit: r1615445 - in /logging/log4j/log4j2/trunk: log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ReflectionComparison.java log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ReflectionBenchmark.java

Author: mattsicker
Date: Sun Aug  3 19:58:05 2014
New Revision: 1615445

URL: http://svn.apache.org/r1615445
Log:
Migrate reflection benchmarks to log4j-perf.

Added:
    logging/log4j/log4j2/trunk/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ReflectionBenchmark.java
Modified:
    logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ReflectionComparison.java

Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ReflectionComparison.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ReflectionComparison.java?rev=1615445&r1=1615444&r2=1615445&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ReflectionComparison.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ReflectionComparison.java Sun Aug  3 19:58:05 2014
@@ -16,98 +16,24 @@
  */
 package org.apache.logging.log4j.core.impl;
 
-import java.lang.reflect.Constructor;
-
-import org.apache.logging.log4j.categories.PerformanceTests;
-import org.apache.logging.log4j.core.util.Timer;
-import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.StringFormattedMessage;
 import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
 import sun.reflect.Reflection;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertSame;
 
 /**
- * Tests the cost of invoking Reflection.getCallerClass via reflection vs calling it directly.
+ * Verifies that ReflectiveCallerClassUtility behaves as expected compared to {@code sun.reflect.Reflection}.
  */
-@Category(PerformanceTests.class)
 public class ReflectionComparison {
 
-    private static final int COUNT = 1000000;
-
-    @Test
-    public void testReflection() {
-        final Timer timer = new Timer("Reflection", COUNT);
-        timer.start();
-        for (int i= 0; i < COUNT; ++i) {
-            ReflectiveCallerClassUtility.getCaller(3);
-        }
-        timer.stop();
-        System.out.println(timer.toString());
-    }
-
-    @SuppressWarnings("deprecation") // yeah, yeah, we know that they're trying to remove this API
-    @Test
-    public void testDirectly() {
-        final Timer timer = new Timer("Directly", COUNT);
-        timer.start();
-        for (int i= 0; i < COUNT; ++i) {
-
-            Reflection.getCallerClass(3);
-        }
-        timer.stop();
-        System.out.println(timer.toString());
-    }
-
-    @SuppressWarnings("deprecation")
     @Test
     public void testBothMethodsReturnTheSame() {
-        assertSame("1 is not the same.",
-                Reflection.getCallerClass(1 + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
-                ReflectiveCallerClassUtility.getCaller(1));
-        assertSame("2 is not the same.",
-                Reflection.getCallerClass(2 + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
-                ReflectiveCallerClassUtility.getCaller(2));
-        assertSame("3 is not the same.",
-                Reflection.getCallerClass(3 + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
-                ReflectiveCallerClassUtility.getCaller(3));
-        assertSame("4 is not the same.",
-                Reflection.getCallerClass(4 + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
-                ReflectiveCallerClassUtility.getCaller(4));
-        assertSame("5 is not the same.",
-                Reflection.getCallerClass(5 + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
-                ReflectiveCallerClassUtility.getCaller(5));
-        assertSame("6 is not the same.",
-                Reflection.getCallerClass(6 + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
-                ReflectiveCallerClassUtility.getCaller(6));
-    }
-
-    @Test
-    public void testCreateObjects() throws Exception {
-        Timer timer = new Timer("CreatObjects", COUNT);
-        timer.start();
-        for (int i = 0; i < COUNT; ++i) {
-            new StringFormattedMessage("Hello %1", i);
+        for (int i = 1; i <= 6; i++) {
+            assertSame(String.format("%d is not the same", i),
+                Reflection.getCallerClass(i + ReflectiveCallerClassUtility.JAVA_7U25_COMPENSATION_OFFSET),
+                ReflectiveCallerClassUtility.getCaller(i)
+            );
         }
-        timer.stop();
-        System.out.println(timer.toString());
-        final Class<? extends Message> clazz = StringFormattedMessage.class;
-
-        timer = new Timer("ReflectionObject", COUNT);
-        timer.start();
-
-        for (int i = 0; i < COUNT; ++i) {
-            createMessage(clazz, "Hello %1", i);
-        }
-        timer.stop();
-        System.out.println(timer.toString());
-    }
-
-    private Message createMessage(final Class<? extends Message> clazz, final String msg, final Object... params) throws Exception {
-        final Constructor<? extends Message> constructor = clazz.getConstructor(String.class, Object[].class);
-        return constructor.newInstance(msg, params);
     }
 
 }

Added: logging/log4j/log4j2/trunk/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ReflectionBenchmark.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ReflectionBenchmark.java?rev=1615445&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ReflectionBenchmark.java (added)
+++ logging/log4j/log4j2/trunk/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ReflectionBenchmark.java Sun Aug  3 19:58:05 2014
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.perf.jmh;
+
+import org.apache.logging.log4j.core.impl.ReflectiveCallerClassUtility;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.StringFormattedMessage;
+import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.logic.BlackHole;
+import sun.reflect.Reflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Random;
+
+/**
+ * <p>Benchmarks the different ways the caller class can be obtained.
+ * To run this in sampling mode (latency test):</p>
+ * <pre>
+ *     java -jar microbenchmarks.jar ".*ReflectionBenchmark.*" -i 5 -f 1 -wi 5 -bm sample -tu ns
+ * </pre>
+ * <p>To run this in throughput testing mode:</p>
+ * <pre>
+ *     java -jar microbenchmarks.jar ".*ReflectionBenchmark.*" -i 5 -f 1 -wi 5 -bm Throughput -tu ms
+ * </pre>
+ */
+public class ReflectionBenchmark {
+
+    @State(Scope.Thread)
+    public static class RandomInteger {
+
+        private final Random r = new Random();
+
+        int random;
+
+        @Setup(Level.Iteration)
+        public void setup() {
+            random = r.nextInt();
+        }
+    }
+
+    @GenerateMicroBenchmark
+    public void testBaseline(final BlackHole bh) {
+    }
+
+    @GenerateMicroBenchmark
+    public String getCallerClassNameFromStackTrace(final BlackHole bh) {
+        return new Throwable().getStackTrace()[3].getClassName();
+    }
+
+    @GenerateMicroBenchmark
+    public String getCallerClassNameReflectively(final BlackHole bh) {
+        return ReflectiveCallerClassUtility.getCaller(3).getName();
+    }
+
+    @GenerateMicroBenchmark
+    public String getCallerClassNameSunReflection(final BlackHole bh) {
+        return Reflection.getCallerClass(3).getName();
+    }
+
+    @GenerateMicroBenchmark
+    public Class<?> getStackTraceClassForClassName() throws ClassNotFoundException {
+        return Class.forName(new Throwable().getStackTrace()[3].getClassName());
+    }
+
+    @GenerateMicroBenchmark
+    public Class<?> getReflectiveCallerClassUtility(final BlackHole bh) {
+        return ReflectiveCallerClassUtility.getCaller(3);
+    }
+
+    @GenerateMicroBenchmark
+    public Class<?> getDirectSunReflection(final BlackHole bh) {
+        return Reflection.getCallerClass(3);
+    }
+
+    @GenerateMicroBenchmark
+    public Message getMessageUsingNew(final RandomInteger rng) {
+        return new StringFormattedMessage("Hello %i", rng.random);
+    }
+
+    @GenerateMicroBenchmark
+    public Message getMessageUsingReflection(final RandomInteger rng)
+        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+        final Constructor<? extends Message> constructor = StringFormattedMessage.class.getConstructor(String.class,
+            Object[].class);
+        return constructor.newInstance("Hello %i", new Object[]{rng.random});
+    }
+}