• 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

  • 相关阅读:
    Eclipse+Pydev +Django搭建开发环境时容易出错的几点
    小白对于数据库的初步理解
    个人PC搭建自己的虚拟服务器
    xss 学习(一)
    python爬虫学习(一)
    php常用函数
    sqlmap基础命令
    metinfo 5.3.19 管理员密码重置
    nmap常用命令
    Web安全开发手册
  • 原文地址:https://www.cnblogs.com/zhjh256/p/10797125.html
Copyright © 2020-2023  润新知