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;
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各种反射性能对比的更多相关文章
- 如何利用缓存机制实现JAVA类反射性能提升30倍
一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> ...
- lua、groovy嵌入到java中的性能对比(转)
lua和groovy都是可以嵌入到java中的脚本语言.lua以高性能著称,与C/C++在游戏开放中有较多使用,groovy是一个基于Java虚拟机(JVM)的敏捷动态语言,在jvm下有着不错的性能. ...
- 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时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]
2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集. 上篇传送门: 2017年的golang.python.p ...
- iOS运行时编程(Runtime Programming)和Java的反射机制对比
运行时进行编程,类似Java的反射.运行时编程和Java反射的对比如下: 1.相同点 都可以实现的功能:获取类信息.属性设置获取.类的动态加载(NSClassFromString(@“clas ...
- java数据库连接池性能对比
这个测试的目的是验证当前常用数据库连接池的性能. testcase Connection conn = dataSource.getConnection(); PreparedStatement st ...
- [java]序列化框架性能对比(kryo、hessian、java、protostuff)
序列化框架性能对比(kryo.hessian.java.protostuff) 简介: 优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Pro ...
- java io读取性能对比
背景 从最早bio的只支持阻塞的bio(同步阻塞) 到默认阻塞支持非阻塞nio(同步非阻塞+同步阻塞)(此时加入mmap类) 再到aio(异步非阻塞) 虽然这些api改变了调用模式,但真正执行效率上是 ...
- Java模板引擎性能对比
模板引擎性能对比 从Github上翻到对JSP.Thymeleaf 3.Velocity 1.7.Freemarker 2.3.23几款主流模板的性能对比,总体上看,Freemarker.Veloci ...
随机推荐
- Linux基础使用
Linux中,日志所在的位置: /var/log/messages 系统默认的日志 /var/log/secure 记录用户的登录信息 查看日志的方法有很多 :head ...
- MySQL No Install zip安装方法
解压 解压安装包到一个目录,比如:D:\Database\mysql-5.1.55 配置 创建配置文件 创建一个my.ini文件,MYSQL目录下有几个my开头的ini文件,是针对不同配置使用,具体可 ...
- git 判断路径是否是 git 仓库
git 判断路径是否是 git 仓库 import subprocess repo_dir = "../path/to/check/" command = ['git', 'rev ...
- Java入门第二季——第4章 多态
第4章 多态 多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作 4-1 Java 中的多态 注意:不能通过父类的引 ...
- spark为什么比hadoop的mr要快?
1.前言 Spark是基于内存的计算,而Hadoop是基于磁盘的计算:Spark是一种内存计算技术. 但是事实上,不光Spark是内存计算,Hadoop其实也是内存计算. Spark和Hadoop的根 ...
- 洛谷-P3808-AC自动机(模板)
链接: https://www.luogu.org/problem/P3808 题意: 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 思路: 模板, 代码: #include < ...
- Gson/Jackson/FastJson工具类
import java.util.ArrayList; import java.util.List; import java.util.Map; import com.google.gson.Gson ...
- MySQL基础练习---牛客网的数据以及典型题目
1 部门表departments 部门no和部门名称 2 部门员工表 dept_emp 每个部门对应的员工信息 3 部门经理表 dept_manager 每个部门的经理信息 4 员工表 employe ...
- react-native-page-listview使用方法(自定义FlatList/ListView下拉刷新,上拉加载更多,方便的实现分页)
react-native-page-listview 对ListView/FlatList的封装,可以很方便的分页加载网络数据,还支持自定义下拉刷新View和上拉加载更多的View.兼容高版本Flat ...
- 多线程:Thread类的Join()方法
多线程:Thread类的Join()方法 http://blog.163.com/hc_ranxu/blog/static/3672318220095284513678/ 当我们在线程B中调用Thre ...