java MVEL2/Spring EL表达式、直接调用、反射性能实测
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表达式、直接调用、反射性能实测的更多相关文章
- Spring EL表达式和资源调用
Spring EL表达式 Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于在jsp的EL表达式语言. Spring 开发中经常涉及调用各种资源的情况, ...
- Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)
一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...
- 把功能强大的Spring EL表达式应用在.net平台
Spring EL 表达式是什么? Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构 ...
- Spring 在 xml配置文件 或 annotation 注解中 运用Spring EL表达式
Spring EL 一:在Spring xml 配置文件中运用 Spring EL Spring EL 采用 #{Sp Expression Language} 即 #{spring表达式} ...
- java学习笔记—EL表达式(38)
EL表达式 EL即Expression Language,主要的任务是帮助开发者简化获取域属性. 但是一般情况下需要使用EL和JSTL结合使用. 语法: ${ // 隐含对象|直接写域中的属性 } ...
- java之Spring集成CXF简单调用
简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF.CXF 继承了 Celtix 和 X ...
- Java Web(六) EL表达式
这也是属于JSP范围内的知识,使用EL表达式,能更好的使用JSP中的各种内置对象和作用域,说点闲话,马上要出去实习了,有点恐慌,可能这是马上要出去工作的学生的通病,继续努力把,兵来将挡水来土掩, -- ...
- 使用spring EL表达式+自定义切面封装缓存模块
需求是这样的,业务代码需要使用到缓存功能以减少数据库压力,使用redis来实现,并且需要生成缓存的key由方法的传参拼接而成(貌似也只能这样才能保证同样的select查询可以使用缓存),简单的方式就是 ...
- 解决spring el表达式不起作用
el表达式不起作用,如下图所示 现象: 在显示页面中加入: <%@ page isELIgnored="false" %>就OK了 参考:http://bbs.csdn ...
随机推荐
- STL详细介绍(更新中~~~)
目录 string string的常见构造函数 string与char *(或const char*)之间的转换 string 转化为const char* const char* 转化为string ...
- "人工智能",你怕了吗?
近期“人工智能+”,已经是市场上非常火的一个风口,人工智能已经渗透到人类生活的方方面面,服务于我们的生活.但是人工智能的迅速发展,也引起了我的担忧,一系列科技电影展示出来的人工智能奴役人类的场景,让人 ...
- IDEA实用教程(九)—— 创建Servlet
4. 创建Servlet 1) 第一步 2) 第二步 3) 第三步 4) 第四步 由于新创建的Web项目, 没有Tomcat环境, 所以创建的Servlet会发生导包错误,如下图所示 : 因此我们需要 ...
- Vue项目中自动将px转换为rem
一.配置与安装步骤: 1.在 Vue 项目的 src 文件夹下创建一个 config 文件夹: 2.在 config 文件夹中创建 rem.js: 3.将以下代码复制到 rem.js 中: // 基准 ...
- 剑指offer:用两个栈实现一个队列
题目 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解题思路 用一个栈A来保存入栈,当要出栈的时候,将栈A的元素按照栈后进先出的特点转移到栈B中(此时栈A为空了 ...
- 零基础python教程-用Python设计你的第一个小游戏
学以致用,既然学习了python就要让它来实现我们想做的东西,这次咱就用python来做个简单小游戏,在实践中不断成长. 1.游戏代码: 输入数字,来猜测原作者心中所想的数字,猜中夸你,猜不中不夸你, ...
- pandas数据类型判断(三)数据判断
1.函数:空值判断 1)判断数值是否为空用 pd.isna,pd.isnull,np.isnan2)判断字符串是否为空用 pd.isna,pd.isnull:3)判断时间是否为空用 pd.isna,p ...
- SpringBoot第一次案例(以及jar包的生成)
一.Springboot简介 Springboot框架就用于简化Spring应用的开发,约定大于配置,去繁从简.从以往的“Spring全家桶时代”正式过渡到”Spring boot,J2EE一站式解决 ...
- 布局 Bootstrap Table的 文本内容 垂直居中
原文:https://blog.csdn.net/peng_hong_fu/article/details/70662979 样式(注意样式优先级): #div-component-info .tab ...
- (10)打鸡儿教你Vue.js
事件处理器 <div id="app"> <button v-on:click="counter += 1">增加 1</butt ...