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. STL详细介绍(更新中~~~)

    目录 string string的常见构造函数 string与char *(或const char*)之间的转换 string 转化为const char* const char* 转化为string ...

  2. "人工智能",你怕了吗?

    近期“人工智能+”,已经是市场上非常火的一个风口,人工智能已经渗透到人类生活的方方面面,服务于我们的生活.但是人工智能的迅速发展,也引起了我的担忧,一系列科技电影展示出来的人工智能奴役人类的场景,让人 ...

  3. IDEA实用教程(九)—— 创建Servlet

    4. 创建Servlet 1) 第一步 2) 第二步 3) 第三步 4) 第四步 由于新创建的Web项目, 没有Tomcat环境, 所以创建的Servlet会发生导包错误,如下图所示 : 因此我们需要 ...

  4. Vue项目中自动将px转换为rem

    一.配置与安装步骤: 1.在 Vue 项目的 src 文件夹下创建一个 config 文件夹: 2.在 config 文件夹中创建 rem.js: 3.将以下代码复制到 rem.js 中: // 基准 ...

  5. 剑指offer:用两个栈实现一个队列

    题目 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解题思路 用一个栈A来保存入栈,当要出栈的时候,将栈A的元素按照栈后进先出的特点转移到栈B中(此时栈A为空了 ...

  6. 零基础python教程-用Python设计你的第一个小游戏

    学以致用,既然学习了python就要让它来实现我们想做的东西,这次咱就用python来做个简单小游戏,在实践中不断成长. 1.游戏代码: 输入数字,来猜测原作者心中所想的数字,猜中夸你,猜不中不夸你, ...

  7. pandas数据类型判断(三)数据判断

    1.函数:空值判断 1)判断数值是否为空用 pd.isna,pd.isnull,np.isnan2)判断字符串是否为空用 pd.isna,pd.isnull:3)判断时间是否为空用 pd.isna,p ...

  8. SpringBoot第一次案例(以及jar包的生成)

    一.Springboot简介 Springboot框架就用于简化Spring应用的开发,约定大于配置,去繁从简.从以往的“Spring全家桶时代”正式过渡到”Spring boot,J2EE一站式解决 ...

  9. 布局 Bootstrap Table的 文本内容 垂直居中

    原文:https://blog.csdn.net/peng_hong_fu/article/details/70662979 样式(注意样式优先级): #div-component-info .tab ...

  10. (10)打鸡儿教你Vue.js

    事件处理器 <div id="app"> <button v-on:click="counter += 1">增加 1</butt ...