最新添加(2009-3-1),糾正文章錯(cuò)誤
http://www.iteye.com/topic/336082
原帖
1. 背景???? 大家都知道,Java的反射調(diào)用性能要遠(yuǎn)低于直接對象調(diào)用,一般慢10-20倍多,但很多地方反射調(diào)用又是必須的,例如:BeanUtils.copyValues,ORM框架底層等對象映射創(chuàng)建等。因此有的開源框架通過asm等代碼生成方式來優(yōu)化Java反射調(diào)用的性能。
??? cglib中提供了Fast反射功能,包括FastClass,F(xiàn)astMethod等,替代 Java的標(biāo)準(zhǔn)實(shí)現(xiàn),以圖提高性能。
2. 問題
?? 但我在實(shí)測中發(fā)現(xiàn),cglib的Fast反射框架性能反而不如 JDK的標(biāo)準(zhǔn)反射實(shí)現(xiàn).
?? 測試用例:對ManageLogVO的兩個(gè)實(shí)例進(jìn)行copyValue,其中第一個(gè)是標(biāo)準(zhǔn)方式創(chuàng)建和復(fù)制,第二個(gè)通過反射方式創(chuàng)建和賦值。
?? 分別采用 Java直接對象操作: testCopyValue();
??????????? JDK標(biāo)準(zhǔn)反射調(diào)用,? testCopyValueUseReflection();
??????????? Cglib Fast反射:??? testCopyValueUseCglib();
? 執(zhí)行10000次,盡量模擬真實(shí)環(huán)境情況。
3. 測試結(jié)果
?? 下面是實(shí)測結(jié)果,記錄執(zhí)行10000次總耗用時(shí)間:
? testCopyValue????????????? 31ms
? testCopyValueUseReflection 609ms
? testCopyValueUseCglib????? 922ms
? 反射耗時(shí)是直接操作的20倍,F(xiàn)ast反射更是對象直接操作的30倍。
4 代碼片段:
1) 直接操作(共8個(gè)屬性操作,限于篇幅只列出2個(gè)):
2) JDK 反射
? 3) Cglib Fast反射
? 通過JProfiler分析,結(jié)果類似,并且可以發(fā)現(xiàn) FastClass.getMethod(), FastClass.create(),FastMethod.invoke() 分別是耗時(shí)大戶,造成性能低下。
5 優(yōu)化建議:
??? 我的測試用例,基本模擬了真實(shí)ORM框架下的一些操作。instance每次創(chuàng)建,method每次都要查找,而由于 getMethod是性能消耗的主要地方,因此,可以考慮對Method做緩存處理,無論對于 JDK反射還是 Cglib fast反射都有一倍以上的性能提高。
??
引用
真心接受批評,并感謝 sdh5724 指正。
好久沒看這個(gè)貼了,用 sdh5724? 提醒的方式 beanCopier 復(fù)制,效率很高,是標(biāo)準(zhǔn)Java反射調(diào)用的 1/5.
10000次對象復(fù)制測試結(jié)果(ms):
task 直接復(fù)制????????????????? 31
task java標(biāo)準(zhǔn)反射復(fù)制????????? 610
task cglib Fast復(fù)制(不好的寫法) 890
task cglib beancopier復(fù)制??? 125
好久沒看這個(gè)貼了,用 sdh5724? 提醒的方式 beanCopier 復(fù)制,效率很高,是標(biāo)準(zhǔn)Java反射調(diào)用的 1/5.
10000次對象復(fù)制測試結(jié)果(ms):
task 直接復(fù)制????????????????? 31
task java標(biāo)準(zhǔn)反射復(fù)制????????? 610
task cglib Fast復(fù)制(不好的寫法) 890
task cglib beancopier復(fù)制??? 125
原帖
1. 背景???? 大家都知道,Java的反射調(diào)用性能要遠(yuǎn)低于直接對象調(diào)用,一般慢10-20倍多,但很多地方反射調(diào)用又是必須的,例如:BeanUtils.copyValues,ORM框架底層等對象映射創(chuàng)建等。因此有的開源框架通過asm等代碼生成方式來優(yōu)化Java反射調(diào)用的性能。
??? cglib中提供了Fast反射功能,包括FastClass,F(xiàn)astMethod等,替代 Java的標(biāo)準(zhǔn)實(shí)現(xiàn),以圖提高性能。
2. 問題
?? 但我在實(shí)測中發(fā)現(xiàn),cglib的Fast反射框架性能反而不如 JDK的標(biāo)準(zhǔn)反射實(shí)現(xiàn).
?? 測試用例:對ManageLogVO的兩個(gè)實(shí)例進(jìn)行copyValue,其中第一個(gè)是標(biāo)準(zhǔn)方式創(chuàng)建和復(fù)制,第二個(gè)通過反射方式創(chuàng)建和賦值。
?? 分別采用 Java直接對象操作: testCopyValue();
??????????? JDK標(biāo)準(zhǔn)反射調(diào)用,? testCopyValueUseReflection();
??????????? Cglib Fast反射:??? testCopyValueUseCglib();
? 執(zhí)行10000次,盡量模擬真實(shí)環(huán)境情況。
3. 測試結(jié)果
?? 下面是實(shí)測結(jié)果,記錄執(zhí)行10000次總耗用時(shí)間:
? testCopyValue????????????? 31ms
? testCopyValueUseReflection 609ms
? testCopyValueUseCglib????? 922ms
? 反射耗時(shí)是直接操作的20倍,F(xiàn)ast反射更是對象直接操作的30倍。
4 代碼片段:
1) 直接操作(共8個(gè)屬性操作,限于篇幅只列出2個(gè)):
ManagelogVO newVO = new ManagelogVO(); newVO.setLogid(managelogVO.getLogid()); newVO.setOprcode(managelogVO.getOprcode());
2) JDK 反射
Object o = null; try { Class clazz = Class.forName("demo.cglib.ManagelogVO"); o = clazz.newInstance(); Method setterMethod = null; Method getterMethod = null; Object v = null; setterMethod = clazz.getMethod("setLogid", new Class[]{Long.class}); getterMethod = clazz.getMethod("getLogid", null); v = getterMethod.invoke(managelogVO, null); setterMethod.invoke(o, new Object[]{v}); setterMethod = clazz.getMethod("setOprcode", new Class[]{String.class}); getterMethod = clazz.getMethod("getOprcode", null); v = getterMethod.invoke(managelogVO, null); setterMethod.invoke(o, new Object[]{v});
? 3) Cglib Fast反射
Object o = null; try { Class clazz0 = Class.forName("demo.cglib.ManagelogVO"); // FastClass clazz = FastClass.create(clazz0); o = clazz.newInstance(); FastMethod setterMethod = null; FastMethod getterMethod = null; Object v = null; setterMethod = clazz.getMethod("setLogid", new Class[]{Long.class}); getterMethod = clazz.getMethod("getLogid", null); v = getterMethod.invoke(managelogVO, new Object[]{}); setterMethod.invoke(o, new Object[]{v}); setterMethod = clazz.getMethod("setOprcode", new Class[]{String.class}); getterMethod = clazz.getMethod("getOprcode", null); v = getterMethod.invoke(managelogVO, new Object[]{}); setterMethod.invoke(o, new Object[]{v});
? 通過JProfiler分析,結(jié)果類似,并且可以發(fā)現(xiàn) FastClass.getMethod(), FastClass.create(),FastMethod.invoke() 分別是耗時(shí)大戶,造成性能低下。

5 優(yōu)化建議:
??? 我的測試用例,基本模擬了真實(shí)ORM框架下的一些操作。instance每次創(chuàng)建,method每次都要查找,而由于 getMethod是性能消耗的主要地方,因此,可以考慮對Method做緩存處理,無論對于 JDK反射還是 Cglib fast反射都有一倍以上的性能提高。
??
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
