1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.commons.ognl.test;
21
22 import org.apache.commons.ognl.Ognl;
23 import org.apache.commons.ognl.OgnlContext;
24 import org.apache.commons.ognl.OgnlException;
25 import org.apache.commons.ognl.SimpleNode;
26 import org.apache.commons.ognl.test.objects.Bean1;
27
28 import java.lang.reflect.Method;
29 import java.text.DecimalFormat;
30 import java.text.NumberFormat;
31
32 public class Performance
33 {
34
35 private static int MAX_ITERATIONS = -1;
36
37 private static boolean ITERATIONS_MODE;
38
39 private static long MAX_TIME = -1L;
40
41 private static boolean TIME_MODE;
42
43 private static NumberFormat FACTOR_FORMAT = new DecimalFormat( "0.000" );
44
45 private String _name;
46
47 private OgnlContext _context = (OgnlContext) Ognl.createDefaultContext( null );
48
49 private Bean1 _root = new Bean1();
50
51 private SimpleNode _expression;
52
53 private SimpleNode _compiledExpression;
54
55 private Method _method;
56
57 private int _iterations;
58
59 private String _expressionString;
60
61 private boolean _isMvel = false;
62
63 private long t0;
64
65 private long t1;
66
67
68
69
70
71 private static class Results
72 {
73
74 int iterations;
75
76 long time;
77
78 boolean mvel;
79
80 public Results( int iterations, long time, boolean mvel )
81 {
82 super();
83 this.iterations = iterations;
84 this.time = time;
85 this.mvel = mvel;
86 }
87
88 public String getFactor( Results otherResults )
89 {
90 String ret;
91
92 if ( TIME_MODE )
93 {
94 float factor;
95
96 if ( iterations < otherResults.iterations )
97 {
98 factor =
99 Math.max( (float) otherResults.iterations, (float) iterations )
100 / Math.min( (float) otherResults.iterations, (float) iterations );
101 }
102 else
103 {
104 factor =
105 Math.min( (float) otherResults.iterations, (float) iterations )
106 / Math.max( (float) otherResults.iterations, (float) iterations );
107 }
108
109 ret = FACTOR_FORMAT.format( factor );
110 if ( iterations > otherResults.iterations )
111 ret += " times faster than ";
112 else
113 ret += " times slower than ";
114
115 }
116 else
117 {
118 float factor =
119 Math.max( (float) otherResults.time, (float) time )
120 / Math.min( (float) otherResults.time, (float) time );
121
122 ret = FACTOR_FORMAT.format( factor );
123 if ( time < otherResults.time )
124 ret += " times faster than ";
125 else
126 ret += " times slower than ";
127 }
128
129 return ret;
130 }
131 }
132
133
134
135
136
137 public static void main( String[] args )
138 {
139 for ( int i = 0; i < args.length; i++ )
140 {
141 if ( args[i].equals( "-time" ) )
142 {
143 TIME_MODE = true;
144 MAX_TIME = Long.parseLong( args[++i] );
145 }
146 else if ( args[i].equals( "-iterations" ) )
147 {
148 ITERATIONS_MODE = true;
149 MAX_ITERATIONS = Integer.parseInt( args[++i] );
150 }
151 }
152 if ( !TIME_MODE && !ITERATIONS_MODE )
153 {
154 TIME_MODE = true;
155 MAX_TIME = 1500;
156 }
157
158 try
159 {
160 Performance[] tests =
161 new Performance[] {
162 new Performance( "Constant", "100 + 20 * 5", "testConstantExpression" ),
163
164 new Performance( "Single Property", "bean2", "testSinglePropertyExpression" ),
165 new Performance( "Property Navigation", "bean2.bean3.value", "testPropertyNavigationExpression" ),
166
167
168
169
170
171 new Performance( "Property Navigation and Comparison", "bean2.bean3.value <= 24",
172 "testPropertyNavigationAndComparisonExpression" ),
173
174
175
176
177
178
179 new Performance( "Property Navigation with Map Access", "bean2.bean3.map['foo']",
180 "testPropertyNavigationWithMapExpression" ),
181
182
183
184
185
186 };
187
188 boolean timeMode = TIME_MODE;
189 boolean iterMode = ITERATIONS_MODE;
190 long maxTime = MAX_TIME;
191 int maxIterations = MAX_ITERATIONS;
192
193
194
195
196
197 runTests( tests, false );
198
199 TIME_MODE = timeMode;
200 ITERATIONS_MODE = iterMode;
201 MAX_TIME = maxTime;
202 MAX_ITERATIONS = maxIterations;
203
204 System.out.println( "\n\n============================================================================\n" );
205
206 Thread.sleep( 2500 );
207 runTests( tests, true );
208
209
210
211 System.out.println( "\n\n============================================================================\n" );
212
213
214 }
215 catch ( Exception ex )
216 {
217 ex.printStackTrace();
218 }
219 }
220
221 static void runTests( Performance[] tests, boolean output )
222 throws Exception
223 {
224 for ( Performance perf : tests )
225 {
226 try
227 {
228
229 Results javaResults = perf.testJava( ), interpretedResults = perf.testExpression( false ),
230 compiledResults = perf.testExpression( true );
231
232 if ( !output )
233 {
234 return;
235 }
236
237 System.out.println( ( compiledResults.mvel ? "MVEL" : "OGNL" ) + " " + perf.getName( ) + ": "
238 + perf.getExpression( ) );
239 System.out.println(
240 " java: " + javaResults.iterations + " iterations in " + javaResults.time + " ms" );
241
242 System.out.println(
243 " compiled: " + compiledResults.iterations + " iterations in " + compiledResults.time + " ms ("
244 + compiledResults.getFactor( javaResults ) + "java)" );
245
246 System.out.println(
247 "interpreted: " + interpretedResults.iterations + " iterations in " + interpretedResults.time
248 + " ms (" + interpretedResults.getFactor( javaResults ) + "java)" );
249
250 System.out.println( );
251
252 }
253 catch ( OgnlException ex )
254 {
255 ex.printStackTrace( );
256 }
257 }
258 }
259
260
261
262
263
264 public Performance( String name, String expressionString, String javaMethodName )
265 throws Exception
266 {
267 this( name, expressionString, javaMethodName, false );
268 }
269
270 public Performance( String name, String expressionString, String javaMethodName, boolean mvel )
271 throws Exception
272 {
273 _name = name;
274 _isMvel = mvel;
275 _expressionString = expressionString;
276
277 try
278 {
279 _method = getClass().getMethod( javaMethodName, new Class[] {} );
280 }
281 catch ( Exception ex )
282 {
283 throw new OgnlException( "java method not found", ex );
284 }
285
286 if ( !_isMvel )
287 {
288 _expression = (SimpleNode) Ognl.parseExpression( expressionString );
289 _compiledExpression = (SimpleNode) Ognl.compileExpression( _context, _root, expressionString );
290 Ognl.getValue( _expression, _context, _root );
291 _context.put( "contextValue", "cvalue" );
292 }
293 else
294 {
295
296 }
297 }
298
299
300
301
302
303 protected void startTest()
304 {
305 _iterations = 0;
306 t0 = t1 = System.currentTimeMillis();
307 }
308
309 protected Results endTest()
310 {
311 return new Results( _iterations, t1 - t0, _isMvel );
312 }
313
314 protected boolean done()
315 {
316 _iterations++;
317 t1 = System.currentTimeMillis();
318
319 if ( TIME_MODE )
320 {
321 return ( t1 - t0 ) >= MAX_TIME;
322 }
323 else
324 {
325 if ( ITERATIONS_MODE )
326 {
327 return _iterations >= MAX_ITERATIONS;
328 }
329 else
330 {
331 throw new RuntimeException( "no maximums specified" );
332 }
333 }
334 }
335
336
337
338
339
340 public String getName()
341 {
342 return _name;
343 }
344
345 public String getExpression()
346 {
347 return _expressionString;
348 }
349
350 public Results testExpression( boolean compiled )
351 throws Exception
352 {
353 startTest();
354 do
355 {
356 if ( !_isMvel )
357 {
358 if ( compiled )
359 Ognl.getValue( _compiledExpression.getAccessor(), _context, _root );
360 else
361 Ognl.getValue( _expression, _context, _root );
362 }
363 else
364 {
365
366
367
368 }
369 }
370 while ( !done() );
371 return endTest();
372 }
373
374 public Results testJava()
375 throws OgnlException
376 {
377 try
378 {
379 return (Results) _method.invoke( this );
380 }
381 catch ( Exception ex )
382 {
383 throw new OgnlException( "invoking java method '" + _method.getName() + "'", ex );
384 }
385 }
386
387 public Results testConstantExpression()
388 throws OgnlException
389 {
390 startTest();
391 do
392 {
393 @SuppressWarnings( "unused" )
394 int result = 100 + 20 * 5;
395 }
396 while ( !done() );
397 return endTest();
398 }
399
400 public Results testSinglePropertyExpression()
401 throws OgnlException
402 {
403 startTest();
404 do
405 {
406 _root.getBean2();
407 }
408 while ( !done() );
409 return endTest();
410 }
411
412 public Results testPropertyNavigationExpression()
413 throws OgnlException
414 {
415 startTest();
416 do
417 {
418 _root.getBean2().getBean3().getValue();
419 }
420 while ( !done() );
421 return endTest();
422 }
423
424 public Results testPropertyNavigationSetting()
425 throws OgnlException
426 {
427 startTest();
428 do
429 {
430 _root.getBean2().getBean3().setNullValue( "a value" );
431 }
432 while ( !done() );
433 return endTest();
434 }
435
436 public Results testPropertyNavigationAndComparisonExpression()
437 throws OgnlException
438 {
439 startTest();
440 do
441 {
442 @SuppressWarnings( "unused" )
443 boolean result = _root.getBean2().getBean3().getValue() < 24;
444 }
445 while ( !done() );
446 return endTest();
447 }
448
449 public Results testIndexedPropertyNavigationExpression()
450 throws OgnlException
451 {
452 startTest();
453 do
454 {
455 _root.getBean2().getBean3().getIndexedValue( 25 );
456 }
457 while ( !done() );
458 return endTest();
459 }
460
461 public Results testPropertyNavigationWithMapSetting()
462 throws OgnlException
463 {
464 startTest();
465 do
466 {
467 _root.getBean2().getBean3().getMap().put( "bam", "bam" );
468 }
469 while ( !done() );
470 return endTest();
471 }
472
473 public Results testPropertyNavigationWithMapExpression()
474 throws OgnlException
475 {
476 startTest();
477 do
478 {
479 _root.getBean2().getBean3().getMap().get( "foo" );
480 }
481 while ( !done() );
482 return endTest();
483 }
484 }