一、OGNL & MVEL
关于OGNL的使用参见: http://www.ibm.com/developerworks/cn/opensource/os-cn-ognl/
关于MVEL的使用参见:http://mvel.codehaus.org/Getting+Started+for+2.0
二、性能
关于OGNL&MVEL两者的性能一开始看到 http://mvel.codehaus.org/Performance+of+MVEL+2.0 等等一系列的 测试报告的时候几乎都要相信的放弃OGNL了
并且在第一篇文章中也有OGNL和java原始调用的对比,实际测试也发现大有不同。
然后实际测试结果发现最使用新版本,都做最优化的时候两者均相差不大。当然在都不做预编译的时候MVEL 确实好于OGNL
直接上代码:
//direct invoke
long time01 = new Date().getTime();
String dirResult="";
for (int i = 0; i < 100000; i++) {
dirResult= person.getDog().getName();
}
long time02 = new Date().getTime();
System.out.println("direct invoke :"+(time02 - time01));
//MVEL invoke
long time1 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
MVEL.eval("p.dog.name", varMap);
}
long time2 = new Date().getTime();
System.out.println("mvel invoke:"+(time2 - time1));
//MVEL compiled invoke
OptimizerFactory.setDefaultOptimizer("ASM");
ExecutableAccessor compiled2 = (ExecutableAccessor) MVEL.compileExpression("p.dog.name");
long time3 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
String name = (String) MVEL.executeExpression(compiled2, varMap);
}
long time4 = new Date().getTime();
System.out.println("mv compiled invoke:" + (time4 - time3));
//OGNL invoke
long time6 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
Ognl.getValue("#person.dog.name", context, context.getRoot());
}
long time7 = new Date().getTime();
System.out.println("ognl invoke:" + (time7 - time6));
//OGNL compile invoke
OgnlContext context2 = new OgnlContext();// 实现了map接口
context.setRoot(person);
Node node = Ognl.compileExpression(context2, context2.getRoot(), "dog.name");
context2.putAll(context);
long time8 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
node.getAccessor().get(context, context.getRoot());
}
long time9 = new Date().getTime();
System.out.println("ognl compile invoke:" + (time9 - time8));
//OGNL compile invoke
long time18 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
Ognl.getValue(node, context, context.getRoot());
}
long time19 = new Date().getTime();
System.out.println("ognl compile invoke 2:" + (time19 - time18));
//OGNL parse invoke
Object expre = Ognl.parseExpression("#person.dog.name");
long time10 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
Ognl.getValue(expre, context, context.getRoot());
node.getAccessor().get(context, context.getRoot());
}
long time11 = new Date().getTime();
System.out.println("ognl parse invoke:" + (time11 - time10));
结果如下:
direct invoke :5
mvel invoke:672
mv compiled invoke:74
ognl invoke:2402
ognl compile invoke:88
ognl compile invoke 2:88
ognl parse invoke:178
版本信息:
OGNL:3.0.1
MVEL:2.2.0
JDK:1.7.0_55
三、结论:
1、都进行预编译的时候 OGNL& MVEL 性能相差不大。
2、默认直接使用 MVEL 优于 OGNL。
3、相比java执行调用还是20倍左右的差距。