对各种方法实现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;
public String getName() {
return name;
}
public SimpleBean setName(String name) {
this.name = name;
}
}

注意定义要严格遵守JavaBean规范,否则在使用和反射相关工具时会出现NoSuchMethodException异常,或者导致性能非常差,JavaBean规范中最重要的几点如下:

1.类必须是public, 拥有public无参构造器,这样能够通过反射newInstance()动态构建对象.
String className = ...;
Class beanClass = Class.forName(className);
Object beanInstance = beanClass.newInstance();
2.因为反射newInstance使用的是无参构造器, 所以对象实例化和配置是分开的
3.每一个property都有一个public的getter和setter方法, 命名方式是get/set+首字母大写的property名

经测试在SimpleBean为public时,1亿次调用method.invoke方法:

javaReflectGet 100000000 times using 218 ms

而SimpleBean为默认包可见时,1一亿次调用method.invoke方法:

javaReflectGet 100000000 times using 12955 ms

2.测试代码 

public class TestIterator {
private long times = 100_000_000L;
private SimpleBean bean;
private String formatter = "%s %d times using %d ms";
@Before
public void setUp() throws Exception {
bean = new SimpleBean();
bean.setName("haoyifen");
}
//直接通过Java的get方法
@Test
public void directGet() {
Stopwatch watch = Stopwatch.createStarted();
for (long i = 0; i < times; i++) {
bean.getName();
}
watch.stop();
String result = String.format(formatter, "directGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
System.out.println(result);
}
//通过高性能的ReflectAsm库进行测试,仅进行一次methodAccess获取
@Test
public void reflectAsmGet() {
MethodAccess methodAccess = MethodAccess.get(SimpleBean.class);
Stopwatch watch = Stopwatch.createStarted();
for (long i = 0; i < times; i++) {
methodAccess.invoke(bean, "getName");
}
watch.stop();
String result = String.format(formatter, "reflectAsmGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
System.out.println(result);
}
//通过Java Class类自带的反射获得Method测试,仅进行一次method获取
@Test
public void javaReflectGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Method getName = SimpleBean.class.getMethod("getName");
Stopwatch watch = Stopwatch.createStarted();
for (long i = 0; i < times; i++) {
getName.invoke(bean);
}
watch.stop();
String result = String.format(formatter, "javaReflectGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
System.out.println(result);
}
//使用Java自带的Property属性获取Method测试,仅进行一次method获取
@Test
public void propertyGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, IntrospectionException {
Method method = null;
BeanInfo beanInfo = Introspector.getBeanInfo(SimpleBean.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (propertyDescriptor.getName().equals("name")) {
method = propertyDescriptor.getReadMethod();
break;
}
}
Stopwatch watch = Stopwatch.createStarted();
for (long i = 0; i < times; i++) { method.invoke(bean);
}
watch.stop();
String result = String.format(formatter, "propertyGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
System.out.println(result);
}
//BeanUtils的getProperty测试
@Test
public void beanUtilsGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Stopwatch watch = Stopwatch.createStarted();
for (long i = 0; i < times; i++) {
BeanUtils.getProperty(bean, "name");
}
watch.stop();
String result = String.format(formatter, "beanUtilsGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
System.out.println(result);
}
}

3.测试结果

在4核i5-4590@3.30GHz机器上跑以上测试,经过多次测量,基本在以下数值范围附近,测试数据如下:

1. directGet 100000000 times using 37 ms

2. reflectAsmGet 100000000 times using 39 ms

3. javaReflectGet 100000000 times using 222 ms

4. propertyGet 100000000 times using 335 ms

5. beanUtilsGet 100000000 times using 20066 ms

4.结果分析

1.使用reflectAsm库的性能能和直接调用get方法持平

2.Java自带的反射性能大致为直接get的1/6和1/9.

3.BeanUtils的getProperty非常的慢,为直接get性能的1/500,为Java自带反射性能的1/100和1/60.

为什么BeanUtils的getProperty方法性能这么慢?

Java各种反射性能对比的更多相关文章

  1. 如何利用缓存机制实现JAVA类反射性能提升30倍

    一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> ...

  2. lua、groovy嵌入到java中的性能对比(转)

    lua和groovy都是可以嵌入到java中的脚本语言.lua以高性能著称,与C/C++在游戏开放中有较多使用,groovy是一个基于Java虚拟机(JVM)的敏捷动态语言,在jvm下有着不错的性能. ...

  3. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)

    2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...

  4. 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]

    2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集.   上篇传送门: 2017年的golang.python.p ...

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

    运行时进行编程,类似Java的反射.运行时编程和Java反射的对比如下:   1.相同点   都可以实现的功能:获取类信息.属性设置获取.类的动态加载(NSClassFromString(@“clas ...

  6. java数据库连接池性能对比

    这个测试的目的是验证当前常用数据库连接池的性能. testcase Connection conn = dataSource.getConnection(); PreparedStatement st ...

  7. [java]序列化框架性能对比(kryo、hessian、java、protostuff)

    序列化框架性能对比(kryo.hessian.java.protostuff) 简介:   优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Pro ...

  8. java io读取性能对比

    背景 从最早bio的只支持阻塞的bio(同步阻塞) 到默认阻塞支持非阻塞nio(同步非阻塞+同步阻塞)(此时加入mmap类) 再到aio(异步非阻塞) 虽然这些api改变了调用模式,但真正执行效率上是 ...

  9. Java模板引擎性能对比

    模板引擎性能对比 从Github上翻到对JSP.Thymeleaf 3.Velocity 1.7.Freemarker 2.3.23几款主流模板的性能对比,总体上看,Freemarker.Veloci ...

随机推荐

  1. Hadoop_17_MapRduce_案例2_实现用户手机流量统计(ReduceTask并行度控制)

    需求:1.统计每一个用户(手机号)所耗费的总上行流量.下行流量,总流量 1.数据如下:保存为.dat文件(因为以\t切分数据,文件格式必须合适) 1363157985066 13726230503 0 ...

  2. vue-element-admin后台的安装

    # 克隆项目 git clone https://github.com/PanJiaChen/vue-element-admin.git # 进入项目目录 cd vue-element-admin # ...

  3. Ping-Pong (Easy Version)的解析

    原题链接:http://codeforces.com/problemset/problem/320/B 之前自己做的时候一直读不懂题意,看了大佬的博客才知道是用dfs写,一道暴力搜索大水题https: ...

  4. string::begin

    iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; const_ite ...

  5. 在Visual Studio Code 运行 webpack ./src/main.js --output-filename ./dist/bundle.js --output-path . --mode development 提示 Module no t found:Error:Can't resolve' 'jquery' 是因为vs code还没安装jquery

    在Visual Studio Code 运行 webpack ./src/main.js --output-filename ./dist/bundle.js --output-path . --mo ...

  6. 从json到python解析python,从bson到monogdb

    1.JSON JSON是JavaScript Object Notation的缩写,中文译为JavaScript对象表示法.用来作为数据交换的文本格式,作用类似于XML,而2001年Douglas C ...

  7. 【leetcode】1290. Convert Binary Number in a Linked List to Integer

    题目如下: Given head which is a reference node to a singly-linked list. The value of each node in the li ...

  8. Elasticsearch 读时分词、写时分词

    初次接触 Elasticsearch 的同学经常会遇到分词相关的难题,比如如下这些场景: 为什么明明有包含搜索关键词的文档,但结果里面就没有相关文档呢?我存进去的文档到底被分成哪些词(term)了?我 ...

  9. luogu 1156 垃圾陷阱 动态规划

    Code: #include <bits/stdc++.h> #define N 4004 #define setIO(s) freopen(s".in"," ...

  10. 1-1RGB色彩模式

    http://www.missyuan.com/thread-350716-1-1.html RGB色彩模式 CTRL+O  打开文件 双击{O->Open} F8/菜单-窗口-信息    调出 ...