• 看看java的反射效率


    看看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  
    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  }
  • 相关阅读:
    【xamarin + MvvmCross 从零开始】一、环境安装
    .NET微服务从0到1:服务容错(Polly)
    .NET微服务从0到1:服务注册与发现(Consul)
    .NET微服务从0到1:API网关(Ocelot)
    .NET Core之单元测试(四):Fluent Assertions的使用
    .NET Core之单元测试(三):Mock框架Moq的使用
    .NET Core之单元测试(二):使用内存数据库处理单元测试中的数据库依赖
    .NET Core之单元测试(一):入门
    win+navicat
    JDBC介绍和Mybatis运行原理及事务处理
  • 原文地址:https://www.cnblogs.com/hasv/p/2207073.html
Copyright © 2020-2023  润新知