import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map; import org.mvel2.MVEL; /**
* Id 模型*/
public class Id implements Serializable { private Long id; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public static Long get(Id id) {
return id == null ? null : id.getId();
} public static void main(String[] args) {
Id id = new Id();
long beg = System.currentTimeMillis();
for (long i=0;i<100000;i++) {
id.setId(i);
}
System.out.println(System.currentTimeMillis() - beg); Map<String, Object> paramMap = new HashMap<>();
String expression = "id.setId(1L);";
paramMap.put("id", id);
beg = System.currentTimeMillis();
Serializable compiled =MVEL.compileExpression(expression);
for (long i=0;i<100000;i++) {
MVEL.eval(expression, paramMap); // 非编译模式
// MVEL.executeExpression(compiled,paramMap); // 编译模式
}
System.out.println(System.currentTimeMillis() - beg);
beg = System.currentTimeMillis();
try {
Field field = Id.class.getDeclaredField("id");
for (long i=0;i<100000;i++) {
field.set(id, i);
}
System.out.println(System.currentTimeMillis() - beg);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

输出如下:

6  --原生调用
498   --MVEL2表达式

239 -- MVEL2 编译后
18   --反射

还差一个基于Unsafe直接访问的,后面补上。。。。

可见用表达式的性能是非常低下的,即使是编译后。如果真的什么时候需要用表达式的话,可以采用动态编译java类的方式实现。(它可以通过调用javac实现参考https://www.cnblogs.com/anai/p/4269858.html,也可以调用JavaCompiler,参考https://www.cnblogs.com/jxrichar/p/4883465.html)这样可以同时达到原生调用和灵活性的目标。

根据一些文章的性能评测,对于表达式语言,性能最好的是groovy、其次是MVEL,但是我们实际测下来,简单的语句grovvy的性能远不如mvel2。

网上还有一些OGNL & MVEL的性能测试比较(如https://caoyaojun1988-163-com.iteye.com/blog/2089726,还是比较客观的),实际上到现在2019年,我们会发现最终差别就在于有没有采用javac机制,没有采用javac机制的性能就是差一大截,否则不会相差太多,如果某个库说其性能特别NB如Fel,要么就是特定场景高度定制、要么author就是无脑,如果真有这样两全的方案,该方案要么被作为机密、要么被广泛open source了,不需要打广告。PS:我们在原来在一个稽核系统中采用mvel2对数以百万计的数据进行表达式计算,但是实际性能测试下来发现比原生java代码慢了20多倍,开发拒绝接收,最后我们硬是采用了javac的机制实现该特性,性能和原生java基本上相差不到10%。

当然,作为通用的表达式语言,MVEL2在性能要求不是很苛刻的场景中还是推荐使用的http://simpleframework.net/news/view?newsId=028c6068df804c548668b96db31a912b。

https://www.cnblogs.com/keithmo/p/5186693.html

https://www.techug.com/post/dynamic-code-in-java.html

https://blog.csdn.net/sunnyyoona/article/details/75244442

https://yanguz123.iteye.com/blog/2146176

https://www.iteye.com/topic/361794

https://blog.csdn.net/fhm727/article/details/6543152

http://simpleframework.net/news/view?newsId=028c6068df804c548668b96db31a912b

java MVEL2/Spring EL表达式、直接调用、反射性能实测的更多相关文章

  1. Spring EL表达式和资源调用

    Spring EL表达式     Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于在jsp的EL表达式语言.     Spring 开发中经常涉及调用各种资源的情况, ...

  2. Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)

    一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...

  3. 把功能强大的Spring EL表达式应用在.net平台

    Spring EL 表达式是什么? Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构 ...

  4. Spring 在 xml配置文件 或 annotation 注解中 运用Spring EL表达式

    Spring  EL 一:在Spring xml 配置文件中运用   Spring EL Spring EL 采用 #{Sp Expression  Language} 即 #{spring表达式} ...

  5. java学习笔记—EL表达式(38)

    EL表达式 EL即Expression Language,主要的任务是帮助开发者简化获取域属性. 但是一般情况下需要使用EL和JSTL结合使用. 语法: ${ // 隐含对象|直接写域中的属性 }  ...

  6. java之Spring集成CXF简单调用

    简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF.CXF 继承了 Celtix 和 X ...

  7. Java Web(六) EL表达式

    这也是属于JSP范围内的知识,使用EL表达式,能更好的使用JSP中的各种内置对象和作用域,说点闲话,马上要出去实习了,有点恐慌,可能这是马上要出去工作的学生的通病,继续努力把,兵来将挡水来土掩, -- ...

  8. 使用spring EL表达式+自定义切面封装缓存模块

    需求是这样的,业务代码需要使用到缓存功能以减少数据库压力,使用redis来实现,并且需要生成缓存的key由方法的传参拼接而成(貌似也只能这样才能保证同样的select查询可以使用缓存),简单的方式就是 ...

  9. 解决spring el表达式不起作用

    el表达式不起作用,如下图所示 现象: 在显示页面中加入: <%@ page isELIgnored="false" %>就OK了 参考:http://bbs.csdn ...

随机推荐

  1. c# Queue 类

  2. [ipsec] 特别硬核的ike/ipsec NAT穿越机制分析

    〇 前言 这怕是最后一篇关于IKE,IPSEC的文字了,因为不能没完没了. 所以,我一直在想这个标题该叫什么.总的来说可以将其概括为:IKE NAT穿越机制的分析. 但是,同时它也回答了以下问题: ( ...

  3. [堆栈]Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

    转自:https://blog.csdn.net/yangkuanqaz85988/article/details/52403726 问题1:不同线程/进程拥有着不同的栈,那系统所有的中断用的是同一个 ...

  4. 搭建MySQL MMM高可用

    搭建MMM: 1,安装 agent 节点执行 yum install -y mysql-mmm-agent 2, monitor 节点执行 yum install -y mysql-mmm-monit ...

  5. Integer Inquiry UVA-424(大整数)

    题意分析: 将字符串倒着存入int数组中,每次加完后再取余除去大于10的部分 关键:倒着存入,这样会明显缩短代码量. #include<iostream> #include<cstd ...

  6. pyspark minHash LSH 查找相似度

    先看看官方文档: MinHash for Jaccard Distance MinHash is an LSH family for Jaccard distance where input feat ...

  7. codevs 1341 与3和5无关的数

    题目描述 Description 有一正整数a,如果它能被x整除,或者它的十进制表示法中某位上的数字为x,则称a与x相关.现求所有小于等于n的与3或5无关的正整数的平方和. 输入描述 Input De ...

  8. spring boot学习笔记(二)创建spring boot项目

    用eclipse(需要用高版本,要不然弄不出来):new →Spring Sarter Project 用IDEA:一般默认 一般默认 入门级的先 剩下的一般默认... 一.项目至少有下面的东西,里面 ...

  9. 关于jquery的事件委托-bind,live,delegate,on的区别发展

    1.bind()方法 (只能给已经存在的元素上绑定事件) 只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件. $('ul li').bind('click', function( ...

  10. Homebrew 更新慢问题

    cd "$(brew --repo)" git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/hom ...