看看java的反射效率
2011-10-11 12:30
211 查看
看看java的反射效率
java反射效率到底如何,花了点时间,做了一个简单的测试.供大家参考.测试背景:
1. 测试简单Bean(int,Integer,String)的set方法
2. loop 1亿次
3. 测试代码尽可能避免对象的创建,复发方法的调用,仅仅测试set方法的耗时
测试结果:
场景 | 本机测试结果(XP,双核,2G) | 服务器测试结果(Linux,XEN虚拟机,8核,5.5G) |
方法直接调用 | 235MS | 190MS |
JDK Method调用 | 29188MS | 4633MS |
JDK Method调用(稍作优化) | 5672MS | 4262MS |
Cglib FastMethod调用 | 5390MS | 2787MS |
1.JDK反射效率是直接调用的一个数量级,差不多20倍
2.一个set方法的反射调用时间 = 4633ms / 1亿 / 3次 = 0.0154us
3.Cglib的fastmethod还是有优势的
最后,附上测试代码:
1 /**
2 * <pre>
3 * 本机测试结果(XP,双核,2G):
4 * 直接调用(LOOP=1亿): 235MS
5 * 反射调用(LOOP=1亿): 29188MS
6 * 反射调用(优化)(LOOP=1亿): 5672MS
7 * 放射调用(CGLIB)(LOOP=1亿):5390MS
8 *
9 * 服务器测试结果(linux xen虚拟机,5.5G内存;8核CPU):
10 * 直接调用(LOOP=1亿): 190MS
11 * 反射调用(LOOP=1亿): 4633MS
12 * 反射调用(优化)(LOOP=1亿): 4262MS
13 * 放射调用(CGLIB)(LOOP=1亿):2787MS
14 * </pre>
15 *
16 * @author Stone.J 2010-9-15 上午10:07:27
17 */
18 public class ReflectionTest {
19
20 private static final int DEFAULT_INT = 1 ;
21 private static final Integer DEFAULT_INTEGER = 1 ;
22 private static final String DEFAULT_STRING = " name " ;
23 private static final Object[] DEFAULT_INTS = { 1 };
24 private static final Object[] DEFAULT_INTEGERS = new Integer[] { 1 };
25 private static final Object[] DEFAULT_STRINGS = new String[] { " name " };
26
27 private static final Bean BEAN = new Bean();
28
29 private static final CachedMethod CACHED_METHOD = new CachedMethod();
30 private static final OptimizationCachedMethod OPTIMIZATION_CACHED_METHOD = new OptimizationCachedMethod();
31 private static final CglibCachedMethod CGLIB_CACHED_METHOD = new CglibCachedMethod();
32
33 private static final long LOOP = 1 * 10000 * 10000 ;
34
35 // 测试main
36 public static void main(String[] args) {
37 if (args.length != 1 ) {
38 System.out.println( " args error. " );
39 System.exit( 1 );
40 }
41 int tc = Integer.valueOf(args[ 0 ]);
42
43 long start = System.currentTimeMillis();
44 for ( long i = 0 ; i < LOOP; i ++ ) {
45 switch (tc) {
46 case 1 :
47 // 直接调用
48 test();
49 break ;
50 case 2 :
51 // 反射调用
52 testReflection();
53 break ;
54 case 3 :
55 // 优化后反射调用
56 testOptimizationReflection();
57 break ;
58 case 4 :
59 // cglib反射调用
60 testCglibReflection();
61 break ;
62 default :
63 System.out.println( " tc error. must be [1-4] " );
64 break ;
65 }
66 }
67 long dur = System.currentTimeMillis() - start;
68 System.out.println(dur);
69 }
70
71 // 直接调用测试
72 public static void test() {
73 BEAN.setId(DEFAULT_INT);
74 BEAN.setCode(DEFAULT_INTEGER);
75 BEAN.setName(DEFAULT_STRING);
76 }
77
78 // 反射调用测试
79 public static void testReflection() {
80 try {
81 CACHED_METHOD.setId.invoke(BEAN, DEFAULT_INTS);
82 CACHED_METHOD.setCode.invoke(BEAN, DEFAULT_INTEGERS);
83 CACHED_METHOD.setName.invoke(BEAN, DEFAULT_STRINGS);
84 } catch (Exception e) {
85 e.printStackTrace();
86 }
87 }
88
89 // 优化后反射调用测试
90 public static void testOptimizationReflection() {
91 try {
92 OPTIMIZATION_CACHED_METHOD.setId.invoke(BEAN, DEFAULT_INTS);
93 OPTIMIZATION_CACHED_METHOD.setCode.invoke(BEAN, DEFAULT_INTEGERS);
94 OPTIMIZATION_CACHED_METHOD.setName.invoke(BEAN, DEFAULT_STRINGS);
95 } catch (Exception e) {
96 e.printStackTrace();
97 }
98 }
99
// cglib反射调用测试
public static void testCglibReflection() {
try {
CGLIB_CACHED_METHOD.cglibSetId.invoke(BEAN, DEFAULT_INTS);
CGLIB_CACHED_METHOD.cglibSetCode.invoke(BEAN, DEFAULT_INTEGERS);
CGLIB_CACHED_METHOD.cglibSetName.invoke(BEAN, DEFAULT_STRINGS);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* <pre>
* 测试的bean
* 简单的int Integer String类型
* </pre>
*
* @author Stone.J 2010-9-15 上午10:40:40
*/
public static class Bean {
private int id;
private Integer code;
private String name;
public int getId() {
return id;
}
public void setId( int id) {
this .id = id;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this .code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this .name = name;
}
}
/**
* 反射测试需要:Cached Method
*
* @author Stone.J 2010-9-15 上午10:41:04
*/
public static class CachedMethod {
public Method setId;
public Method setCode;
public Method setName;
{
try {
setId = Bean. class .getDeclaredMethod( " setId " , int . class );
setCode = Bean. class .getDeclaredMethod( " setCode " , Integer. class );
setName = Bean. class .getDeclaredMethod( " setName " , String. class );
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 反射测试需要:优化后的Cached Method
*
* @author Stone.J 2010-9-15 上午10:41:21
*/
public static class OptimizationCachedMethod extends CachedMethod {
{
/** 所谓的优化 */
setId.setAccessible( true );
setCode.setAccessible( true );
setName.setAccessible( true );
}
}
/**
* 反射测试需要,使用cglib的fast method
*
* @author Stone.J 2010-9-15 上午10:51:53
*/
public static class CglibCachedMethod extends CachedMethod {
public FastMethod cglibSetId;
public FastMethod cglibSetCode;
public FastMethod cglibSetName;
private FastClass cglibBeanClass = FastClass.create(Bean. class );
{
cglibSetId = cglibBeanClass.getMethod(setId);
cglibSetCode = cglibBeanClass.getMethod(setCode);
cglibSetName = cglibBeanClass.getMethod(setName);
}
}
}
相关文章推荐
- 看看java的反射效率
- Java反射的效率测试-优先使用FastMethod
- Java如果提高反射效率
- java反射效率及优化
- 转载 java反射效率
- 基于JDK1.7的Java反射效率研究
- 测试Java反射效率
- Java反射三种方式的效率对比
- 反射机制_提高反射效率_操作泛型_操作注解JAVA213
- 今天看看Java反射
- Java反射效率
- 学习笔记——JAVA反射<2>反射机制的效率问题和操作泛型
- java反射详解---具体代码操作看看反射都能干些什么
- java反射究竟消耗多少效率
- JAVA-提高反射效率
- java 反射
- Java反射学习
- JAVA反射获取成员变量构造函数信息
- 深入分析Java方法反射的实现原理
- JAVA加强——反射机制