blob: 0cfaf3958a05abe3a77d17c422221f6b691e6ca0 [file] [log] [blame]
/*
* $Id$
* 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.commons.ognl.test;
import org.apache.commons.ognl.Ognl;
import org.apache.commons.ognl.OgnlContext;
import org.apache.commons.ognl.OgnlException;
import org.apache.commons.ognl.SimpleNode;
import org.apache.commons.ognl.test.objects.Bean1;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class Performance
{
private static int MAX_ITERATIONS = -1;
private static boolean ITERATIONS_MODE;
private static long MAX_TIME = -1L;
private static boolean TIME_MODE;
private static final NumberFormat FACTOR_FORMAT = new DecimalFormat( "0.000" );
private final String _name;
private final OgnlContext _context = (OgnlContext) Ognl.createDefaultContext( null );
private final Bean1 _root = new Bean1();
private SimpleNode _expression;
private SimpleNode _compiledExpression;
private final Method _method;
private int _iterations;
private final String _expressionString;
private boolean _isMvel = false;
private long t0;
private long t1;
/*
* =================================================================== Private static classes
* ===================================================================
*/
private static class Results
{
int iterations;
long time;
boolean mvel;
public Results( int iterations, long time, boolean mvel )
{
this.iterations = iterations;
this.time = time;
this.mvel = mvel;
}
public String getFactor( Results otherResults )
{
String ret;
if ( TIME_MODE )
{
float factor;
if ( iterations < otherResults.iterations )
{
factor =
Math.max( (float) otherResults.iterations, (float) iterations )
/ Math.min( (float) otherResults.iterations, (float) iterations );
}
else
{
factor =
Math.min( (float) otherResults.iterations, (float) iterations )
/ Math.max( (float) otherResults.iterations, (float) iterations );
}
ret = FACTOR_FORMAT.format( factor );
if ( iterations > otherResults.iterations )
ret += " times faster than ";
else
ret += " times slower than ";
}
else
{
float factor =
Math.max( (float) otherResults.time, (float) time )
/ Math.min( (float) otherResults.time, (float) time );
ret = FACTOR_FORMAT.format( factor );
if ( time < otherResults.time )
ret += " times faster than ";
else
ret += " times slower than ";
}
return ret;
}
}
/*
* =================================================================== Public static methods
* ===================================================================
*/
public static void main( String[] args )
{
for ( int i = 0; i < args.length; i++ )
{
if ( args[i].equals( "-time" ) )
{
TIME_MODE = true;
MAX_TIME = Long.parseLong( args[++i] );
}
else if ( args[i].equals( "-iterations" ) )
{
ITERATIONS_MODE = true;
MAX_ITERATIONS = Integer.parseInt( args[++i] );
}
}
if ( !TIME_MODE && !ITERATIONS_MODE )
{
TIME_MODE = true;
MAX_TIME = 1500;
}
try
{
Performance[] tests =
new Performance[] {
new Performance( "Constant", "100 + 20 * 5", "testConstantExpression" ),
// new Performance("Constant", "100 + 20 * 5", "testConstantExpression", false),
new Performance( "Single Property", "bean2", "testSinglePropertyExpression" ),
new Performance( "Property Navigation", "bean2.bean3.value", "testPropertyNavigationExpression" ),
/*
* new Performance("Property Setting with context key", "bean2.bean3.nullValue",
* "testPropertyNavigationSetting"), new Performance("Property Setting with context key",
* "bean2.bean3.nullValue", "testPropertyNavigationSetting", true),
*/
new Performance( "Property Navigation and Comparison", "bean2.bean3.value <= 24",
"testPropertyNavigationAndComparisonExpression" ),
/*
* new Performance("Property Navigation with Indexed Access", "bean2.bean3.indexedValue[25]",
* "testIndexedPropertyNavigationExpression"), new
* Performance("Property Navigation with Indexed Access", "bean2.bean3.indexedValue[25]",
* "testIndexedPropertyNavigationExpression", true),
*/
new Performance( "Property Navigation with Map Access", "bean2.bean3.map['foo']",
"testPropertyNavigationWithMapExpression" ),
/*
* new Performance("Property Navigation with Map value set", "bean2.bean3.map['foo']",
* "testPropertyNavigationWithMapSetting"), new Performance("Property Navigation with Map value set",
* "bean2.bean3.map['foo']", "testPropertyNavigationWithMapSetting", true)
*/
};
boolean timeMode = TIME_MODE;
boolean iterMode = ITERATIONS_MODE;
long maxTime = MAX_TIME;
int maxIterations = MAX_ITERATIONS;
// TIME_MODE = false;
// ITERATIONS_MODE = true;
// maxIterations = 1000;
runTests( tests, false );
TIME_MODE = timeMode;
ITERATIONS_MODE = iterMode;
MAX_TIME = maxTime;
MAX_ITERATIONS = maxIterations;
System.out.println( "\n\n============================================================================\n" );
Thread.sleep( 2500 );
runTests( tests, true );
// Thread.sleep(2000);
System.out.println( "\n\n============================================================================\n" );
// runTests(tests);
}
catch ( Exception ex )
{
ex.printStackTrace();
}
}
static void runTests( Performance[] tests, boolean output )
throws Exception
{
for ( Performance perf : tests )
{
try
{
Results javaResults = perf.testJava( ), interpretedResults = perf.testExpression( false ),
compiledResults = perf.testExpression( true );
if ( !output )
{
return;
}
System.out.println( ( compiledResults.mvel ? "MVEL" : "OGNL" ) + " " + perf.getName( ) + ": "
+ perf.getExpression( ) );
System.out.println(
" java: " + javaResults.iterations + " iterations in " + javaResults.time + " ms" );
System.out.println(
" compiled: " + compiledResults.iterations + " iterations in " + compiledResults.time + " ms ("
+ compiledResults.getFactor( javaResults ) + "java)" );
System.out.println(
"interpreted: " + interpretedResults.iterations + " iterations in " + interpretedResults.time
+ " ms (" + interpretedResults.getFactor( javaResults ) + "java)" );
System.out.println( );
}
catch ( OgnlException ex )
{
ex.printStackTrace( );
}
}
}
/*
* =================================================================== Constructors
* ===================================================================
*/
public Performance( String name, String expressionString, String javaMethodName )
throws Exception
{
this( name, expressionString, javaMethodName, false );
}
public Performance( String name, String expressionString, String javaMethodName, boolean mvel )
throws Exception
{
_name = name;
_isMvel = mvel;
_expressionString = expressionString;
try
{
_method = getClass().getMethod( javaMethodName, new Class[] {} );
}
catch ( Exception ex )
{
throw new OgnlException( "java method not found", ex );
}
if ( !_isMvel )
{
_expression = (SimpleNode) Ognl.parseExpression( expressionString );
_compiledExpression = (SimpleNode) Ognl.compileExpression( _context, _root, expressionString );
Ognl.getValue( _expression, _context, _root );
_context.put( "contextValue", "cvalue" );
}
else
{
// _mvelCompiled = MVEL.compileExpression(expressionString);
}
}
/*
* =================================================================== Protected methods
* ===================================================================
*/
protected void startTest()
{
_iterations = 0;
t0 = t1 = System.currentTimeMillis();
}
protected Results endTest()
{
return new Results( _iterations, t1 - t0, _isMvel );
}
protected boolean done()
{
_iterations++;
t1 = System.currentTimeMillis();
if ( TIME_MODE )
{
return ( t1 - t0 ) >= MAX_TIME;
}
else
{
if ( ITERATIONS_MODE )
{
return _iterations >= MAX_ITERATIONS;
}
else
{
throw new RuntimeException( "no maximums specified" );
}
}
}
/*
* =================================================================== Public methods
* ===================================================================
*/
public String getName()
{
return _name;
}
public String getExpression()
{
return _expressionString;
}
public Results testExpression( boolean compiled )
throws Exception
{
startTest();
do
{
if ( !_isMvel )
{
if ( compiled )
Ognl.getValue( _compiledExpression.getAccessor(), _context, _root );
else
Ognl.getValue( _expression, _context, _root );
}
else
{
/*
* if (compiled) MVEL.executeExpression(_mvelCompiled, _root); else MVEL.eval(_expressionString, _root);
*/
}
}
while ( !done() );
return endTest();
}
public Results testJava()
throws OgnlException
{
try
{
return (Results) _method.invoke( this );
}
catch ( Exception ex )
{
throw new OgnlException( "invoking java method '" + _method.getName() + "'", ex );
}
}
public Results testConstantExpression()
throws OgnlException
{
startTest();
do
{
@SuppressWarnings( "unused" )
int result = 100 + 20 * 5;
}
while ( !done() );
return endTest();
}
public Results testSinglePropertyExpression()
throws OgnlException
{
startTest();
do
{
_root.getBean2();
}
while ( !done() );
return endTest();
}
public Results testPropertyNavigationExpression()
throws OgnlException
{
startTest();
do
{
_root.getBean2().getBean3().getValue();
}
while ( !done() );
return endTest();
}
public Results testPropertyNavigationSetting()
throws OgnlException
{
startTest();
do
{
_root.getBean2().getBean3().setNullValue( "a value" );
}
while ( !done() );
return endTest();
}
public Results testPropertyNavigationAndComparisonExpression()
throws OgnlException
{
startTest();
do
{
@SuppressWarnings( "unused" )
boolean result = _root.getBean2().getBean3().getValue() < 24;
}
while ( !done() );
return endTest();
}
public Results testIndexedPropertyNavigationExpression()
throws OgnlException
{
startTest();
do
{
_root.getBean2().getBean3().getIndexedValue( 25 );
}
while ( !done() );
return endTest();
}
public Results testPropertyNavigationWithMapSetting()
throws OgnlException
{
startTest();
do
{
_root.getBean2().getBean3().getMap().put( "bam", "bam" );
}
while ( !done() );
return endTest();
}
public Results testPropertyNavigationWithMapExpression()
throws OgnlException
{
startTest();
do
{
_root.getBean2().getBean3().getMap().get( "foo" );
}
while ( !done() );
return endTest();
}
}