Reduce SpEL compilation restrictions on mathematical expressions
Prior to this change the SpEL compiler would not compile mathematical expressions where the operands were of differing types (e.g. int and double). This required the expression writer to do the conversion in the expression text. For example: T(Integer).valueOf(someInt).doubleValue()/35d With this commit the restriction is lifted and it is more like Java so that you can simply do someInt/35d. The mathematical operators affected are divide/plus/minus/multiply and modulus. This change involved removing some guards so that the exitTypeDescriptor (the trigger for whether compilation is allowed) is set more frequently and enhancing bytecode generation to perform more sophisticated conversion/coercion automatically. Issue: SPR-12789
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,6 +63,98 @@ public class SpelCompilationPerformanceTests extends AbstractExpressionTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static class NumberHolder {
|
||||
public int payload = 36;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies the new support for compiling mathematical expressions with
|
||||
* different operand types.
|
||||
*/
|
||||
@Test
|
||||
public void compilingMathematicalExpressionsWithDifferentOperandTypes() throws Exception {
|
||||
NumberHolder nh = new NumberHolder();
|
||||
expression = parser.parseExpression("(T(Integer).valueOf(payload).doubleValue())/18D");
|
||||
Object o = expression.getValue(nh);
|
||||
assertEquals(2d,o);
|
||||
System.out.println("Performance check for SpEL expression: '(T(Integer).valueOf(payload).doubleValue())/18D'");
|
||||
long stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
compile(expression);
|
||||
System.out.println("Now compiled:");
|
||||
o = expression.getValue(nh);
|
||||
assertEquals(2d, o);
|
||||
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
|
||||
expression = parser.parseExpression("payload/18D");
|
||||
o = expression.getValue(nh);
|
||||
assertEquals(2d,o);
|
||||
System.out.println("Performance check for SpEL expression: 'payload/18D'");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
compile(expression);
|
||||
System.out.println("Now compiled:");
|
||||
o = expression.getValue(nh);
|
||||
assertEquals(2d, o);
|
||||
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
stime = System.currentTimeMillis();
|
||||
for (int i=0;i<1000000;i++) {
|
||||
o = expression.getValue(nh);
|
||||
}
|
||||
System.out.println("One million iterations: "+(System.currentTimeMillis()-stime)+"ms");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inlineLists() throws Exception {
|
||||
expression = parser.parseExpression("{'abcde','ijklm'}[0].substring({1,3,4}[0],{1,3,4}[1])");
|
||||
|
||||
Reference in New Issue
Block a user