java动态表达式、原生调用、反射性能对比

package net.hs.cw.bomp.utils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.mvel2.MVEL;

/**
 * Id 模型
 *
 * @author Gavin Hu
 * @create 2015/8/26
 */
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   --反射

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

根据一些文章的性能评测,对于表达式语言,性能最好的是groovy、其次是MVEL。

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://www.iteye.com/topic/361794

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

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

原文地址:https://www.cnblogs.com/zhjh256/p/10797125.html

时间: 2024-10-04 05:23:49

java动态表达式、原生调用、反射性能对比的相关文章

Java各种反射性能对比

对各种方法实现get方法的性能进行了一个测试. 总共有5个测试,,每个测试都是执行1亿次 1. 直接通过Java的get方法 2.通过高性能的ReflectAsm库进行测试 3.通过Java Class类自带的反射获得Method测试 4.使用Java自带的Property类获取Method测试 5.BeanUtils的getProperty测试 1 测试用Bean类 测试定义了如下一个bean类. public class SimpleBean { private String name; p

Java Tomcat vs PHP CLI Server 性能对比

测试环境: Ubuntu 14.04 with i5-3230M Tomcat 8.0.5 with 64bit jre1.7.0_55 PHP 5.5.8 with Zend OPcache v7.0.3-dev 测试脚本: 显示当前服务器时间 Java Tomcat: t.jsp <%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8&

Java动态代理机制研读

java动态加载类(反射机制) /*MyClass.java*/ public class MyClass { public int id; public String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.

Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. cglib封装了asm,可以在运行期动态生成新的class. cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制. 原理区别: java动态代理是利用反射机

java动态加载指定的类或者jar包反射调用其方法

序言 有时候,项目中会用到java动态加载指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大降低,更加的模块化,代码利用率更高.模式中的代理模式就用到java的这一机制.下边就让我们通过代码来看看如何实现此功能. 代码详细 package loadjarclass; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoad

java动态载入指定的类或者jar包反射调用其方法

序言 有时候.项目中会用到java动态载入指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大减少,更加的模块化.代码利用率更高.模式中的代理模式就用到java的这一机制. 下边就让我们通过代码来看看怎样实现此功能. 代码具体 package loadjarclass; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoa

Java 动态的创建注入代码,注入方法给类或者接口并通过反射调用

1.将要被注入的类: /* * 文 件 名: JNAUtil.java * 版 权: Sunny Technologies Co., Ltd. Copyright YYYY-YYYY, All rights reserved * 描 述: <描述> * 修 改 人: L.Hao * 修改时间: 2014-11-11 * 跟踪单号: <跟踪单号> * 修改单号: <修改单号> * 修改内容: <修改内容> */ package com.test; import

[转] 利用表达式树构建委托改善反射性能

最近搞一个系统时由于在比较关键地方用到反射了,所以要关注了一下反射的性能问题.搜索一下,不难搜到老赵的这篇文章,下面是一些杂乱的笔记.(建议先看老赵的文章) .Net4.0反射性能改善 看老赵的文章,老赵得到的结果是这样的: 1 00:00:00.0125539 (Directly invoke) 2 00:00:04.5349626 (Reflection invoke) 3 00:00:00.0322555 (Dynamic executor) 而我把代码搞下来自己运行得到这样的结果: 1

iOS运行时编程(Runtime Programming)和Java的反射机制对比

运行时进行编程,类似Java的反射.运行时编程和Java反射的对比如下: 1.相同点 都可以实现的功能:获取类信息.属性设置获取.类的动态加载(NSClassFromString(@“className”)).方法的动态调用 下面是iOS中涉及到的相关使用方法 类的动态加载:NSClassFromString(@“className”),方法的动态调用:NSSelectorFormString(@”doSonethingMethod:”) 常见的方法: isKindOfClass: isMemb