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

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

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

    設(shè)計(jì)java

    j2ee輕量級(jí)框架,IMVC,IORM && web網(wǎng)絡(luò)游戲

    java反射性能測(cè)試分析

        java有別于其他編程語(yǔ)言而讓我著迷的特性有很多,其中最喜歡的是接口設(shè)計(jì),他讓我們?cè)O(shè)計(jì)的東西具有美感。同樣反射也是我比較喜歡的一個(gè)特性,他讓程序自動(dòng)運(yùn)行,動(dòng)態(tài)加載成為了可能,同時(shí)也是現(xiàn)在很多流行框架所必不可少的特性,struts,hibernate等都是,spring本身就是基于反射的就更不用說(shuō)了。細(xì)細(xì)想來(lái),似乎很少有不涉及到反射的框架。我自己設(shè)計(jì)框架的時(shí)候,開(kāi)始也都是運(yùn)用反射,但是越深入?yún)s讓我越疑惑,反射的效率一直是我設(shè)計(jì)框架的心病。

        今天在優(yōu)化InstantMVC的時(shí)候就考慮怎么提高自動(dòng)封裝form的效率,struts是用的commons-beantuils,好像也沒(méi)人說(shuō)struts的效率不高,誠(chéng)然,beanUtils中很多有用方便的特性讓反射開(kāi)發(fā)者著迷,但是通過(guò)我今天的測(cè)試,卻發(fā)現(xiàn)beanUtils的易用性要付出巨大的性能代價(jià),雖然在現(xiàn)在這個(gè)年代,這么點(diǎn)性能不算什么,但是對(duì)于我這種執(zhí)著的人開(kāi)發(fā)執(zhí)著的框架,還是對(duì)性能有種獨(dú)特的偏好,目前來(lái)說(shuō)InstantMVC中用的是直接的反射簡(jiǎn)單封裝,而InstantORM(我的持久層框架)中用到是自動(dòng)生成pojo和相應(yīng)的pojo輔助類(lèi)來(lái)實(shí)現(xiàn)動(dòng)態(tài)高效(比直接的反射高效10-20倍)執(zhí)行Object的方法(一般是get和set),對(duì)于InstantMVC的form利用動(dòng)態(tài)生成輔助類(lèi)有一定的難度,不是說(shuō)實(shí)現(xiàn)難度,而是對(duì)于運(yùn)用該框架的web開(kāi)發(fā)者來(lái)說(shuō),不夠直接。所以還是主要考慮用反射的,廢話不說(shuō),下面開(kāi)始今天的測(cè)試。

        首先,測(cè)試主要有三部分組成,測(cè)試創(chuàng)建對(duì)象的性能,測(cè)試set方法的性能,測(cè)試get方法的性能。我沒(méi)有看過(guò)beanUtils的源代碼,不過(guò)評(píng)我的經(jīng)驗(yàn)想想BeanUtils應(yīng)該是做了一些性能的優(yōu)化的,初步猜測(cè)是第一次運(yùn)行緩存Object的相應(yīng)東東(具體是什么也不知道),所以測(cè)試的時(shí)候都是從第二次開(kāi)始,忽略第一次。下面是測(cè)試代碼(省略了異常拋出。)   

       
    public class MyBean {
        String name;
        
    int age;
        String[] firends;
        
    public static void main(String args[]) {
            Object o1
    =beanUtilsCreate();
            Object o2
    =javaCreate();
            MyBean my
    =new MyBean();
            
    long a=System.currentTimeMillis();
           
          
            
    for(int i=0;i<5000;i++){
                
    //47
                
    //beanUtilsCreate();
                
    //15
                
    //javaCreate();
                
    //0
                
    //manualCreate();
                
                
    //235
                
    //beanUtilsSet(o1);
                
    //40
                
    //javaSet(o2);
                
    //0
                
    //manualSet(my);
                
                
    //203
                
    //beanUtilsGet(o1);
                
    //47
                
    //javaGet(o2);
                
    //0
                
    //manualGet(my);
            }
            
    long b=System.currentTimeMillis();
            System.out.println(b
    -a);
        }
        
        
        
    //===============下面是 beanUtils的方法
        public static Object beanUtilsCreate() {
            Object ob
    =ConstructorUtils.invokeConstructor(MyBean.class,null);
            
    return ob;
        }
        
    public static void beanUtilsSet(Object ob) {
            BeanUtils.setProperty(ob, 
    "name""旺旺旺");
        }
        
    public static void beanUtilsGet(Object ob) {
            BeanUtils.getProperty(ob, 
    "name");
        }
        
        
    //    ===============下面是 java自身的直接反射的方法
        public static Object javaCreate() {
            Object ob
    =MyBean.class.newInstance();
            
    return ob;
        }
        
    public static void javaSet(Object ob) {
            Method m
    =MyBean.class.getDeclaredMethod("setName"new Class[]{String.class});
            m.invoke(ob,
    new Object[]{"旺旺旺"});
        }
        
    public static void javaGet(Object ob) {
            Method m
    =MyBean.class.getDeclaredMethod("getName"new Class[0]);
            m.invoke(ob,
    new Object[0]);
        }
        
    //    ===============下面是 手動(dòng)的創(chuàng)建對(duì)象
        public static MyBean manualCreate(){
            MyBean my
    =new MyBean();
            
    return my;
        }
        
    public static void manualSet(MyBean my){
            my.setName(
    "旺旺旺");
        }
        
    public static void manualGet(MyBean my){
            my.getName();
        }
        
        
        
        
    public int getAge() {
            
    return age;
        }
        
    public void setAge(int age) {
            
    this.age = age;
        }
        
    public String[] getFirends() {
            
    return firends;
        }
        
    public void setFirends(String[] firends) {
            
    this.firends = firends;
        }
        
    public String getName() {
            
    return name;
        }
        
    public void setName(String name) {
            
    this.name = name;
        }
    }

        上面代碼首先創(chuàng)建一個(gè)MyBean,簡(jiǎn)單的name和age屬性,然后get和set方法,在main方法中首先構(gòu)建三個(gè)類(lèi):
    Object o1=beanUtilsCreate();
    Object o2
    =javaCreate();
    MyBean my
    =new MyBean();
    為了防止beanUtils內(nèi)部對(duì)第一次做了緩存操作而使測(cè)試不準(zhǔn)確。

    第二次開(kāi)始連續(xù)循環(huán)5000次分別測(cè)試 Create,set,和get的性能。
    結(jié)果顯示如下:

    ===================================================
           BeanUtils   java自己反射   手動(dòng)
    創(chuàng)建:    47          15            0     
    set方法   235         40            0
    get方法   203         47            0

    ===================================================
    jdk 1.6,1G內(nèi)存,AMD 2600+

        從上面的結(jié)果可以看出,BeanUtils的性能確實(shí)不怎么樣,這樣的結(jié)果雖然在現(xiàn)代服務(wù)器都菜價(jià)了的年代,我還是要為struts和spring等基于反射的框架捏一把汗。不知道spring有沒(méi)有對(duì)反射做過(guò)優(yōu)化,不過(guò)上次看Ibatis的時(shí)候好像他提供了一個(gè)配置選項(xiàng)來(lái)增強(qiáng)字節(jié)碼的反射效率,大概就是那種動(dòng)態(tài)創(chuàng)建字節(jié)碼的技術(shù)吧。




    --InstantMVC:j2ee輕量級(jí)mvc框架

    posted on 2008-06-07 16:31 剎那 閱讀(11679) 評(píng)論(12)  編輯  收藏 所屬分類(lèi): java性能分析

    Feedback

    # re: java反射性能測(cè)試分析[未登錄](méi) 2008-06-07 19:40 Ryan

    反射生成對(duì)象,一般來(lái)說(shuō),一次生成多次使用,生成對(duì)象的時(shí)間對(duì)使用對(duì)象來(lái)說(shuō)應(yīng)該算是小的,但是如果你只生成一次,其他的什么都不做,那么本身也沒(méi)什么意義,因?yàn)闆](méi)有做任何動(dòng)作  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-07 20:46 剎那

    @Ryan
    恩,你說(shuō)的有道理,一般生成一次都是緩存然后多次使用,但是對(duì)于有些應(yīng)用卻不竟然,比如struts的formBean,因?yàn)槭窃诙嗑€程情況下,所以不可能多吃重復(fù)應(yīng)用,再比如webwork的action,是非單利模式,也就是每次用戶(hù)請(qǐng)求都要?jiǎng)?chuàng)建一個(gè)action,同樣用到了反射。當(dāng)然可以用clone技術(shù)減少創(chuàng)建成本,但是不可否認(rèn),這種創(chuàng)建一次使用一次的情況還是有的。
    再說(shuō),就算創(chuàng)建一次使用多次,但是每次調(diào)用set和get的開(kāi)銷(xiāo)還是比較大的。  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-08 04:17 YYX

    對(duì)于Spring這種框架來(lái)說(shuō),一個(gè)bean生成了以后是長(zhǎng)時(shí)間存在的。
    而對(duì)于beanUtils這種簡(jiǎn)單應(yīng)用5000次也就是1~2百毫秒時(shí)間,大部分時(shí)間只是執(zhí)行一次,對(duì)于web應(yīng)用,從底層數(shù)據(jù)一直執(zhí)行至表現(xiàn)層,這點(diǎn)開(kāi)銷(xiāo)可以忽略不計(jì)。
    執(zhí)行效能優(yōu)化以系統(tǒng)架構(gòu)選擇,儲(chǔ)存策略,數(shù)據(jù)表數(shù)據(jù)庫(kù)和SQL優(yōu)化為主。
    而且beanUtils也在節(jié)約開(kāi)發(fā)時(shí)間同時(shí)也可以使代碼更為通用。
    另:不要把開(kāi)源社區(qū)的人都當(dāng)成神了,像beanUtils這種代碼沒(méi)什么可以?xún)?yōu)化的地方。  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-08 08:30 剎那

    @YYX
    這位老兄一定沒(méi)做過(guò)webwork和spring整合開(kāi)發(fā)。因?yàn)閣ebwork的action是非單利的,用spring整合的時(shí)候需要每次一個(gè)請(qǐng)求反射一個(gè)action,而不是你說(shuō)的都是一次生成長(zhǎng)期使用(雖然在大多數(shù)情況下,spring還是最好弄單利)。
    雖然我知道整個(gè)開(kāi)銷(xiāo)對(duì)于web應(yīng)用是可以忽略的,但是能優(yōu)化,我還是要優(yōu)化的,因?yàn)楫吘棺龅氖强蚣茴?lèi)的東西,如果框架本身性能有問(wèn)題,那么基于它上面的應(yīng)用就比較難說(shuō)了。另外,beanUtils如果你作為一種tools,在平時(shí)開(kāi)發(fā)的時(shí)候用用,那么沒(méi)什么問(wèn)題,但是如果集成到通用框架中,我不敢茍同,因?yàn)楸旧硗ㄓ每蚣苤械慕M件被他人拿出來(lái)重用的可能性很小(保持框架內(nèi)通用可重用即可),權(quán)衡這些,還是覺(jué)得beanUtils這種東西不適合做通用框架下集成,但是卻是和在普通的應(yīng)用中使用。  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-16 12:27 newroc

    每種JDK測(cè)試的效果會(huì)有些差別,我的結(jié)果是BeanUtils 要比自己 直接使用反射要快些的。  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-16 16:06 剎那

    @newroc
    你的是jdk幾?我是1.6  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-17 15:54 z-bro

    仔細(xì)閱讀了這段代碼,并且閱讀了beanutils-1.8.0 ConstructorUtils與setProperty代碼,很遺憾我沒(méi)有發(fā)現(xiàn)有優(yōu)化執(zhí)行效率的跡象存在.在ConstructorUtils部分程序結(jié)構(gòu)相對(duì)簡(jiǎn)單,代碼冗余相對(duì)較小;而setProperty部分,有相當(dāng)部分log代碼(可以通過(guò)開(kāi)關(guān)關(guān)閉),并且有大量的細(xì)致工作代碼.beanutils中在ConstructorUtils與setProperty部分也沒(méi)有緩存的機(jī)制存在.另外補(bǔ)充一句:剎那 的這份測(cè)試代碼都使用了java缺省的類(lèi)加載器,這3種加載(創(chuàng)建)方式(BeanUtils,java自己反射,手動(dòng))在第一次之后,都是使用了ClassLoader的緩存,而并沒(méi)有重新讀類(lèi)文件.
    結(jié)合 剎那 的分析報(bào)告,我個(gè)人認(rèn)為beanutils不能作為強(qiáng)調(diào)高效框架的首選,因?yàn)?quot;如果你只生成一次,其他的什么都不做,那么本身也沒(méi)什么意義",但是如果如YXX考慮的那樣,可能是個(gè)不錯(cuò)的選擇

      回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-25 16:37 YYX

    @剎那
    spring 和struts2的整合項(xiàng)目 我正在做。
    你那個(gè)beanutils運(yùn)行一次要把bean里面的所有g(shù)etter和setter遍歷一次,當(dāng)比你其他的地方專(zhuān)門(mén)指定某方法執(zhí)行的慢多了,要比也要所有屬性get,set一次再和beanutils比。
    另外我說(shuō)的這個(gè)性能差距可以忽略,的確是這樣的,從數(shù)據(jù)庫(kù)以后的邏輯運(yùn)算比起數(shù)據(jù)庫(kù)查詢(xún)需要的時(shí)間,本來(lái)就是可以忽略的。
    就好比一個(gè)億萬(wàn)富翁,不會(huì)一大早出遠(yuǎn)門(mén)到便宜的地方去買(mǎi)菜。哪怕樓下的菜貴10倍,只要東西一樣,就行。  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-06-25 16:50 YYX

    真正要提高性能,不是在這種小地方下手,而是整體架構(gòu)的設(shè)計(jì),查詢(xún)語(yǔ)句,數(shù)據(jù)庫(kù)的配置,緩存的配置,運(yùn)算量的分布。這些方面改善一點(diǎn),比5000次copyProperties()節(jié)約時(shí)間還長(zhǎng)。
      回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析[未登錄](méi) 2008-09-09 22:53 P

    看到beanUtil里面用set/getProperty()了嗎?人家為什么這么做?你那個(gè)類(lèi)有通用性嗎?  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2008-12-08 13:24 WGQQL

    優(yōu)化是針對(duì)瓶頸來(lái)的,樓主列出這些數(shù)據(jù)只是指出這里存在優(yōu)化的可能性,并不是一定要怎么樣吧.
    優(yōu)化也分為2個(gè)方面:人和程序,優(yōu)化就是要這二者之間來(lái)取平衡,基本上的時(shí)候是人的效率太低,所以要犧牲一部分程序的效率來(lái)增加人的效率.  回復(fù)  更多評(píng)論   

    # re: java反射性能測(cè)試分析 2009-03-23 18:50 反射支持者

    你的機(jī)器很爛
    代碼不健壯  回復(fù)  更多評(píng)論   



    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 中文字幕免费在线观看动作大片| 日本视频免费在线| 皇色在线免费视频| 青青青亚洲精品国产| 亚洲图片中文字幕| 亚洲av永久无码精品表情包| www亚洲精品少妇裸乳一区二区 | 亚洲XX00视频| 成年女人免费v片| 最近中文字幕大全中文字幕免费| 香蕉免费看一区二区三区| 国产精品亚洲精品爽爽| 亚洲国产激情在线一区| 亚洲成a人片在线网站| 亚洲AV成人片色在线观看| 亚洲色偷偷偷鲁综合| 久久影视国产亚洲| 亚洲男人av香蕉爽爽爽爽| 国产国产人免费人成免费视频| 性色av免费观看| 久草视频免费在线观看| 2019中文字幕免费电影在线播放| a级特黄毛片免费观看| 亚洲一级片免费看| 国产JIZZ中国JIZZ免费看| 香蕉国产在线观看免费| 一级毛片视频免费| 一级视频在线免费观看| 亚洲阿v天堂在线2017免费| 国产精品无码永久免费888| 国产免费久久精品99久久| 一级视频在线免费观看| 成人无码视频97免费| 中国一级特黄高清免费的大片中国一级黄色片 | 久久免费福利视频| 99久久国产免费-99久久国产免费 99久久国产免费中文无字幕 | 三级毛片在线免费观看| 国产猛男猛女超爽免费视频| 免费污视频在线观看| 最好看最新的中文字幕免费| 亚洲视频在线免费看|