/**
* <copyright>
*
* Copyright (c) 2009, 2010 Springsite BV (The Netherlands) and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Martin Taal - Initial API and implementation
*
* </copyright>
*
* $Id: ReflectivePerformanceTest.java,v 1.3 2011/08/26 14:34:50 mtaal Exp $
*/
package org.eclipse.emf.texo.modelgenerator.test;
import junit.framework.TestCase;
/**
* Tests the performance difference between reflective and direct method calls and with method lookup.
*
* See <a href="http://www.jguru.com/faq/view.jsp?EID=246569">here</a>.
*
* Current result on a dual core 2.50Ghz laptop and server vm:
*
* 100000 regular method calls:1 milliseconds.
*
* 100000 reflective method calls without lookup:104 milliseconds.
*
* 100000 reflective method calls with lookup:245 milliseconds.
*
* 1000000 regular method calls:71 milliseconds.
*
* 1000000 reflective method calls without lookup:1008 milliseconds.
*
* 1000000 reflective method calls with lookup:2334 milliseconds.
*
* 10000000 regular method calls:13 milliseconds.
*
* 10000000 reflective method calls without lookup:10036 milliseconds.
*
* 10000000 reflective method calls with lookup:23577 milliseconds.
*
* @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
* @version $Revision: 1.3 $
*/
public class ReflectivePerformanceTest extends TestCase {
public void testPerformance() throws Exception {
doTestRun(100000, false);
doTestRun(1000000, false);
doTestRun(10000000, false);
doTestRun(100000, false);
doTestRun(1000000, false);
doTestRun(10000000, false);
doTestRun(100000, true);
doTestRun(1000000, true);
doTestRun(10000000, true);
}
private void doTestRun(final int loops, final boolean printResults) throws Exception {
Class<?> c = TestClass.class;
long start = System.currentTimeMillis();
TestClass object = new TestClass();
for (int i = 0; i < loops; i++) {
object.setValue(i);
object.getValue();
}
if (printResults) {
System.out.println(loops + " regular method calls:" //$NON-NLS-1$
+ (System.currentTimeMillis() - start) + " milliseconds."); //$NON-NLS-1$
}
{
object = new TestClass();
java.lang.reflect.Method addMethod = c.getMethod("setValue", //$NON-NLS-1$
long.class);
java.lang.reflect.Method getMethod = c.getMethod("getValue"); //$NON-NLS-1$
start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
addMethod.invoke(object, i);
getMethod.invoke(object);
}
if (printResults) {
System.out.println(loops + " reflective method calls without lookup:" //$NON-NLS-1$
+ (System.currentTimeMillis() - start) + " milliseconds."); //$NON-NLS-1$
}
}
{
object = new TestClass();
start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
java.lang.reflect.Method addMethod = c.getMethod("setValue", //$NON-NLS-1$
long.class);
java.lang.reflect.Method getMethod = c.getMethod("getValue"); //$NON-NLS-1$
addMethod.invoke(object, i);
getMethod.invoke(object);
}
if (printResults) {
System.out.println(loops + " reflective method calls with lookup:" //$NON-NLS-1$
+ (System.currentTimeMillis() - start) + " milliseconds."); //$NON-NLS-1$
}
}
{
object = new TestClass();
java.lang.reflect.Field field = c.getDeclaredField("value"); //$NON-NLS-1$
field.setAccessible(true);
start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
field.set(object, i);
field.get(object);
}
if (printResults) {
System.out.println(loops + " reflective field access without lookup:" //$NON-NLS-1$
+ (System.currentTimeMillis() - start) + " milliseconds."); //$NON-NLS-1$
}
}
}
private class TestClass {
private long value;
public void setValue(final long value) {
this.value = value;
}
public long getValue() {
return value;
}
}
}