看看java的反射效率

看看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  
100        //  cglib反射调用测试
101        public   static   void  testCglibReflection() {
102            try  {
103               CGLIB_CACHED_METHOD.cglibSetId.invoke(BEAN, DEFAULT_INTS);
104               CGLIB_CACHED_METHOD.cglibSetCode.invoke(BEAN, DEFAULT_INTEGERS);
105               CGLIB_CACHED_METHOD.cglibSetName.invoke(BEAN, DEFAULT_STRINGS);
106           }  catch  (Exception e) {
107               e.printStackTrace();
108           }
109       }
110  
111        /**
112        * <pre>
113        * 测试的bean
114        * 简单的int Integer String类型
115        * </pre>
116        * 
117        *  @author  Stone.J 2010-9-15 上午10:40:40
118         */
119        public   static   class  Bean {
120  
121            private   int      id;
122            private  Integer code;
123            private  String  name;
124  
125            public   int  getId() {
126                return  id;
127           }
128  
129            public   void  setId( int  id) {
130                this .id  =  id;
131           }
132  
133            public  Integer getCode() {
134                return  code;
135           }
136  
137            public   void  setCode(Integer code) {
138                this .code  =  code;
139           }
140  
141            public  String getName() {
142                return  name;
143           }
144  
145            public   void  setName(String name) {
146                this .name  =  name;
147           }
148  
149       }
150  
151        /**
152        * 反射测试需要:Cached Method
153        * 
154        *  @author  Stone.J 2010-9-15 上午10:41:04
155         */
156        public   static   class  CachedMethod {
157  
158            public  Method setId;
159            public  Method setCode;
160            public  Method setName;
161  
162           {
163                try  {
164                   setId  =  Bean. class .getDeclaredMethod( " setId " int . class );
165                   setCode  =  Bean. class .getDeclaredMethod( " setCode " , Integer. class );
166                   setName  =  Bean. class .getDeclaredMethod( " setName " , String. class );
167               }  catch  (Exception e) {
168                   e.printStackTrace();
169               }
170           }
171  
172       }
173  
174        /**
175        * 反射测试需要:优化后的Cached Method
176        * 
177        *  @author  Stone.J 2010-9-15 上午10:41:21
178         */
179        public   static   class  OptimizationCachedMethod  extends  CachedMethod {
180  
181           {
182                /**  所谓的优化  */
183               setId.setAccessible( true );
184               setCode.setAccessible( true );
185               setName.setAccessible( true );
186           }
187  
188       }
189  
190        /**
191        * 反射测试需要,使用cglib的fast method
192        * 
193        *  @author  Stone.J 2010-9-15 上午10:51:53
194         */
195        public   static   class  CglibCachedMethod  extends  CachedMethod {
196  
197            public  FastMethod cglibSetId;
198            public  FastMethod cglibSetCode;
199            public  FastMethod cglibSetName;
200  
201            private  FastClass cglibBeanClass  =  FastClass.create(Bean. class );
202  
203           {
204               cglibSetId  =  cglibBeanClass.getMethod(setId);
205               cglibSetCode  =  cglibBeanClass.getMethod(setCode);
206               cglibSetName  =  cglibBeanClass.getMethod(setName);
207           }
208  
209       }
210  
211   }

转载于:https://www.cnblogs.com/hasv/archive/2011/10/11/2207073.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值