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});
+ }
+}