<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    stone2083

    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 }

    posted on 2010-09-15 14:04 stone2083 閱讀(8025) 評論(9)  編輯  收藏 所屬分類: java

    Feedback

    # re: java反射效率 2010-09-15 17:59 王衛華

    如果spring中的bean不使用lazyload并且都是single的,實際上只是啟動過程比glib稍慢,運行起來沒區別,都是動態生成java類  回復  更多評論   

    # re: java反射效率 2010-09-15 20:21 stone2083

    @王衛華
    你是指spring aop中cglib proxy的實現?  回復  更多評論   

    # re: java反射效率 2010-09-16 11:55 Unmi

    學到了,

    不能什么時候都直接用 set 方法的時候,使用 cglib 的 FastClass 效率還是很可觀的啊,Spring、hibernate 等動態框架都用 cglib 的。  回復  更多評論   

    # re: java反射效率 2010-09-16 12:57 stone2083

    @Unmi
    我上面的例子,僅僅是想說明反射調用方法的開銷(不局限在get/set上).
    如果是對java bean getters/setters的操作,可以考慮使用cglib的BulkBean類.
    cglib下的fastclass和fastmethod,確實有一定的優勢,但是優先并不明顯(在jdk1.6上)  回復  更多評論   

    # re: java反射效率[未登錄] 2010-09-18 14:54 阿風

    Cglib的fastmethod 不錯
    回去試用下。
    謝謝立哥=。=  回復  更多評論   

    # re: java反射效率 2011-12-16 11:48 wangwanttt

    啥年代了,JDK1.6里的性能用反射跟正常調用差不了多少了,否則SPRING早就垮了  回復  更多評論   

    # re: java反射效率 2011-12-16 18:06 stone2083

    @wangwanttt
    雖然通過JIT做編譯優化,但和直接方法調用還是有差距的。
    如果你覺得差不多,還請拿出測試數據。謝謝。
      回復  更多評論   

    # re: java反射效率 2013-01-24 18:28 大肥牛

    @wangwanttt
    初始化上反射肯定需要花費更多的時間,spring之所以存在不并不是因為用了反射,而是它本省強大的功能!  回復  更多評論   

    # re: java反射效率 2013-02-07 11:08 WeiPeng

    測試貌似沒有預熱,如果事先預熱一下,反射調用和直接調用差距可能更小。  回復  更多評論   

    主站蜘蛛池模板: 中文字幕亚洲综合久久菠萝蜜 | 久久精品视频免费看| 久久久久国产精品免费看| 亚洲一区二区三区乱码A| 美女一级毛片免费观看| 日本免费人成黄页网观看视频 | 成人黄网站片免费视频 | 亚洲人成色在线观看| 亚洲午夜国产精品无码老牛影视| 久久精品国产亚洲AV无码娇色| 亚洲国产欧美日韩精品一区二区三区| 国产免费牲交视频免费播放| 亚洲成网777777国产精品| 四虎影视久久久免费观看| 国产精品亚洲mnbav网站| a视频在线观看免费| 国产在线不卡免费播放| 亚洲欧洲国产精品久久| 2020久久精品国产免费| 亚洲另类无码专区首页| 亚洲国产专区一区| 亚洲经典千人经典日产| 亚洲精品色婷婷在线影院| 18禁在线无遮挡免费观看网站| 国产乱色精品成人免费视频| 一级做a毛片免费视频| 免费黄色app网站| 国产成人高清亚洲一区久久| 毛片高清视频在线看免费观看| 亚洲最大成人网色| 成人免费网站在线观看| 国产精品无码免费专区午夜| 亚洲∧v久久久无码精品| 青娱乐在线视频免费观看| 久久亚洲国产精品一区二区| ww在线观视频免费观看| 免费人成再在线观看网站| 2022年亚洲午夜一区二区福利| 久久国产精品免费观看| 亚洲熟妇无码AV在线播放| a一级毛片免费高清在线|