| /* |
| * $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(); |
| } |
| } |