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 ...
随机推荐
- python面试总结4(算法与内置数据结构)
算法与内置数据结构 常用算法和数据结构 sorted dict/list/set/tuple 分析时间/空间复杂度 实现常见数据结构和算法 数据结构/算法 语言内置 内置库 线性结构 list(列表) ...
- P1559 运动员最佳匹配问题[最大费用最大流]
题目描述 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势 ...
- Spring Cloud 组件 —— hystrix
作用与功能 ① 资源隔离, 每个依赖配备单独的线程池,为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间.② 依赖超时,可配置依赖调用超时时间,超 ...
- 工作中 99% 能用到的 Git 命令
分支操作 暂存操作 回退操作 标签操作 常规操作 git创建项目仓库 忽略已加入到版本库中的文件 取消忽略文件 拉取.上传免密码. 分支操作 git branch 创建分支 git branch -b ...
- mini_frame(web框架)
文件目录: dynamic中:框架 static:css,jss静态文件 teplates:模板 web_server.conf: 配置文件 web_server.py: 主程序 run.sh:运行脚 ...
- set/priority_queue的运算符重载
#include<bits/stdc++.h> using namespace std; struct cmp { bool operator ()(int a, int b) //重载小 ...
- P3709 大爷的字符串题 脑子+莫队
简化题意:区间众数出现次数??? 为什么?原因是,贪心的想,我们要划分成尽量少的严格递增序列,这样rp掉的最少. 设区间众数出现次数为 \(x\) ,那我们至少要分成 \(x\) 段严格上升序列. # ...
- Oracle ALERT日志中常见监听相关报错之二:ORA-3136错误的排查 (转载)
近期在多个大型系统中遇到此问题,一般来说如果客户端未反映异常的话可以忽略的.如果是客户端登陆时遇到ORA-12170: TNS:Connect timeout occurred,可以参考 http:/ ...
- javaweb上传文件夹
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 首先我们需要了解的是上传文件三要素: 1.表单提交方式:post (get方式提交有大小 ...
- RookeyFrame 添加 导入功能
我遇到的情况: 我在‘模块管理’里面, 把模块‘客户联系人’的‘允许导入’勾上,保存后,在‘客户联系人’页面没有导入按钮, 模块‘客户主数据’却可以, 这是为什么额?两个模块都是线下创建的,是哪儿不一 ...