您的位置:首页 > 编程语言 > Java开发

看看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)
方法直接调用235MS190MS
JDK Method调用29188MS4633MS
JDK Method调用(稍作优化)5672MS4262MS
Cglib FastMethod调用5390MS2787MS
得出一个感性的结果:
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);
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: