幾種copyProperties工具類性能比較

一汗唱、事出有因

前段時間阿里發(fā)布了阿里巴巴代碼規(guī)約插件,果斷將它集成起來。右鍵->阿里編碼規(guī)約掃描,立即將不符合阿里編程規(guī)范的代碼現(xiàn)了原形,不得不服阿里想統(tǒng)一整個java市場的決心啊逝慧。怎么熟掂?竟然看到我最喜歡使用的Apache BeanUtils.copyProperties()方法后面打了個大大的紅叉,提示"避免使用Apache的BeanUtils進(jìn)行屬性的copy"嗜侮。心里確實(shí)不是滋味,從小老師就教導(dǎo)我們,"凡是Apache寫的框架都是好框架",怎么可能會存在"性能問題"--還是這種猿們所不能容忍的問題稽犁。心存著對BeanUtils的懷疑開始了今天的研究之路。

二陨帆、市面上的其他幾種屬性copy工具
  1. springframework的BeanUtils
  2. cglib的BeanCopier
  3. Apache BeanUtils包的PropertyUtils類
三曲秉、下面來測試一下性能。
private static void testCglibBeanCopier(OriginObject origin, int len) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        System.out.println();
        System.out.println("================cglib BeanCopier執(zhí)行" + len + "次================");
        DestinationObject destination3 = new DestinationObject();

        for (int i = 0; i < len; i++) {
            BeanCopier copier = BeanCopier.create(OriginObject.class, DestinationObject.class, false);
            copier.copy(origin, destination3, null);
        }
        stopwatch.stop();

        System.out.println("testCglibBeanCopier 耗時: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }

    private static void testApacheBeanUtils(OriginObject origin, int len)
            throws IllegalAccessException, InvocationTargetException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        System.out.println();
        System.out.println("================apache BeanUtils執(zhí)行" + len + "次================");
        DestinationObject destination2 = new DestinationObject();
        for (int i = 0; i < len; i++) {
            BeanUtils.copyProperties(destination2, origin);
        }

        stopwatch.stop();

        System.out.println("testApacheBeanUtils 耗時: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }

    private static void testSpringFramework(OriginObject origin, int len) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        System.out.println("================springframework執(zhí)行" + len + "次================");
        DestinationObject destination = new DestinationObject();

        for (int i = 0; i < len; i++) {
            org.springframework.beans.BeanUtils.copyProperties(origin, destination);
        }

        stopwatch.stop();

        System.out.println("testSpringFramework 耗時: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }

    private static void testApacheBeanUtilsPropertyUtils(OriginObject origin, int len)
            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        System.out.println();
        System.out.println("================apache BeanUtils PropertyUtils執(zhí)行" + len + "次================");
        DestinationObject destination2 = new DestinationObject();
        for (int i = 0; i < len; i++) {
            PropertyUtils.copyProperties(destination2, origin);
        }

        stopwatch.stop();

        System.out.println("testApacheBeanUtilsPropertyUtils 耗時: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }

分別執(zhí)行1000疲牵、10000承二、100000、1000000次耗時數(shù)(毫秒):

工具名稱 執(zhí)行1000次耗時 10000次 100000次 1000000次
Apache BeanUtils 390ms 854ms 1763ms 8408ms
Apache PropertyUtils 26ms 221ms 352ms 2663ms
spring BeanUtils 39ms 315ms 373ms 949ms
Cglib BeanCopier 64ms 144ms 171ms 309ms
結(jié)論:
  1. Apache BeanUtils的性能最差,不建議使用瑰步。
  2. Apache PropertyUtils100000次以內(nèi)性能還能接受,到百萬級別性能就比較差了,可酌情考慮矢洲。
  3. spring BeanUtils和BeanCopier性能較好,如果對性能有特別要求,可使用BeanCopier,不然spring BeanUtils也是可取的。
四缩焦、Apache BeanUtils.copyProperties()性能分析

執(zhí)行1000000次copy屬性,然后通過jvisualvm查看方法耗時,如圖:


最耗時方法.png

發(fā)現(xiàn)最耗時的方法就是method.invoke(),但是spring的BeanUtils读虏、PropertyUtils里也是采用反射來實(shí)現(xiàn)的,為什么效率相差這么大呢?

Paste_Image.png

看來Abstract.convert()和getIntrospectionData()占用了很大一部分時間.而且Apache BeanUtils中的日志輸出也比較耗時袁滥。

五盖桥、看看Spring BeanUtils和PropertyUtils
Apache BeanUtils和PropertyUtils對比.png

PropertyUtils和Apache BeanUtils核心代碼區(qū)別在圖中標(biāo)注的地方。Apache BeanUtils主要集中了各種豐富的功能(日志题翻、轉(zhuǎn)換揩徊、解析等等),導(dǎo)致性能變差。

而Spring BeanUtils則是直接通過反射來讀取和寫入,直抒胸臆,省去了其他繁雜的步驟,性能自然不差嵌赠。

Paste_Image.png
六塑荒、Cglib BeanCopier

cglib BeanCopier的主要耗時方法就在BeanCopier.create(),如果將該方法做成靜態(tài)成員變量,則還可以大大縮小執(zhí)行時間。BeanCopier是一種基于字節(jié)碼的方式,其實(shí)就是通過字節(jié)碼方式轉(zhuǎn)換成性能最好的get姜挺、set方式,只需考慮創(chuàng)建BeanCopier的開銷,如果我們將BeanCopier做成靜態(tài)的,基本只需考慮get齿税、set的開銷,所以性能接近于get、set炊豪。BeanCopier源碼分析可見:http://www.reibang.com/p/f8b892e08d26,我這里就不展開了凌箕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拧篮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子牵舱,更是在濱河造成了極大的恐慌串绩,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芜壁,死亡現(xiàn)場離奇詭異礁凡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沿盅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門把篓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腰涧,你說我怎么就攤上這事∥珊疲” “怎么了窖铡?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坊谁。 經(jīng)常有香客問我费彼,道長,這世上最難降的妖魔是什么口芍? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任箍铲,我火速辦了婚禮,結(jié)果婚禮上鬓椭,老公的妹妹穿的比我還像新娘颠猴。我一直安慰自己,他們只是感情好小染,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布翘瓮。 她就那樣靜靜地躺著,像睡著了一般裤翩。 火紅的嫁衣襯著肌膚如雪资盅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天踊赠,我揣著相機(jī)與錄音呵扛,去河邊找鬼。 笑死筐带,一個胖子當(dāng)著我的面吹牛今穿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播烫堤,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼荣赶,長吁一口氣:“原來是場噩夢啊……” “哼凤价!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拔创,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤利诺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后剩燥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慢逾,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年灭红,在試婚紗的時候發(fā)現(xiàn)自己被綠了侣滩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡变擒,死狀恐怖君珠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娇斑,我是刑警寧澤策添,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站毫缆,受9級特大地震影響唯竹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苦丁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一浸颓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧旺拉,春花似錦产上、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至淘太,卻和暖如春姻僧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蒲牧。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工撇贺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冰抢。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓松嘶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挎扰。 傳聞我的和親對象是個殘疾皇子翠订,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理巢音,服務(wù)發(fā)現(xiàn),斷路器尽超,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,822評論 6 342
  • 從三月份找實(shí)習(xí)到現(xiàn)在官撼,面了一些公司,掛了不少似谁,但最終還是拿到小米傲绣、百度、阿里巩踏、京東秃诵、新浪、CVTE塞琼、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,253評論 11 349
  • 就這么頹廢下去吧 就這樣吧 只要墮入深海 就不需要救贖
    露義蓮華君閱讀 303評論 0 0