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

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

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

    posts - 11, comments - 9, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    Clojure 性能 tips(翻譯)

    Posted on 2012-07-29 14:15 steven.cui 閱讀(1953) 評論(2)  編輯  收藏 所屬分類: clojure

    原文章寫在Google Groups thread里,但是還是值得再說下。

    有朋友把Java和Clojure的一些代碼片段放在Clojure Google group里比較,并提到Java的性能要比Clojure快太多了,疑問到底Clojure能不能趕上Java?

    在我的一個開源項目clj-starcraft中,關于java的性能問題,實際上也是我始終面對的,在我寫這篇文章的時,我的Clojure代碼還是慢了Java代碼6倍(Clojure花了70秒解析了1050個文件,Java則只有12秒)

    然而,70秒對過去的速度而言不算太糟糕,在剛開始的時候,竟然花了10分鐘來分析1050個文件。甚至比我用Python實現的還要慢。

    感謝Java的profiler和熱情的Clojure朋友,下面列出了我在提升Clojure性能方面的一些tips:


    (set! *warn-on-reflection* true)

    這恐怕是最重要的一個提升:打開這個設置將會警告你在任何一處用到Java反射API的方法和屬性。如你所想,直接調用永遠比反射要快,不管哪里Clojure都會你不能解析這個方法,你需要自己用type hint方式來避免反射調用。關于使用type hint,Clojure官方站點給了一個如何使用和提速的例子。

    修復所有關于*warn-on-reflection* 的編譯警告后,我的clj-starcraft從10分鐘降到了3分半。


    強制設置數據類型

    Clojure可以使用Java的基礎數據類型,無論何時在循環的時候,堅決考慮將你的值強制轉換成基礎類型,這將大幅提高你的性能。基礎數據類型在Clojure官方網站有例子和如何進行強制轉換來提高性能。


    使用二元運算符

    Clojure可以在一行里面支持多個表達式,但對于運算操作符,只有在兩個的時候才被inlined,如果你發現自己的運算符已經超過了兩個,或許該考慮重寫你的代碼讓操作符顯示的成為兩個。下面請看兩者之間的比較:

    user> (time (dotimes [_ 1e7] (+ 2 4 5)))

    "Elapsed time: 1200.703487 msecs"

    user> (time (dotimes [_ 1e7] (+ 2 (+ 4 5))))

    "Elapsed time: 241.716554 msecs"


    使用==代替=

    使用==比較數字來代替=,提升性能那是相當明顯:

    user> (time (dotimes [i 1e7] (= i i)))

    "Elapsed time: 230.797482 msecs"

    user> (time (dotimes [i 1e7] (== i i)))

    "Elapsed time: 5.143681 msecs"


    避免vectors的destructing binding

    在一段循環種,如果你想為了提升可讀性從vector中傳出值,考慮下標訪問來代替destructing binding。雖然代碼看起來更清晰,但卻非常慢。

    user> (let [v [1 2 3]]

            (time

             (dotimes [_ 1e7]

               (let [[a b c] v]

                 a b c))))

    "Elapsed time: 537.239895 msecs"

    user> (let [v [1 2 3]]

            (time

             (dotimes [_ 1e7]

               (let [a (v 0)

                     b (v 1)

                     c (v 2)]

                 a b c))))

    "Elapsed time: 12.072122 msecs"


    優先使用本地變量

    如果你需要在循環中查詢一個值,你或許需要考慮使用本地變量(通過let定義)來代替全局變量??聪聝烧叩臅r間對比:

    user> (time

           (do

             (def x 1)

             (dotimes [_ 1e8]

               x)))

    "Elapsed time: 372.373304 msecs"

    user> (time

           (let [x 1]

             (dotimes [_ 1e8]

               x)))

    "Elapsed time: 3.479041 msecs"

    如果你想使用本地變量來提升性能,可以考慮下面比較土的式的方式來避免全局變量:

    (let [local-x x]

      (defn my-fn [a b c]

        ...))

    使用profiler工具:

    JVM有兩個profiler工具, -Xprof和-Xrunhprof,找到程序瓶頸而不是瞎猜。


    最后說明:

    你已經注意到,在這些性能提升中,通過調用百萬量的執行來提升了幾百毫秒的性能。所以,不到萬不得已需要提升性能的時候,沒必要讓你的代碼看起來不夠清晰。

    原文地址: http://gnuvince.wordpress.com/2009/05/11/clojure-performance-tips/

    最后補充:可以通過指定編譯為static方法來提高性能:

    pasting

     

    (defn
      ^{:static true}
      fib
      [n]
      (loop [a (long 1) b (long 1) i (long 1) r (list 1 1)]
        (if (== n i)
        r
        (recur b (+ a b) (inc i) (conj r (+ a b))))))

     

     


    評論

    # re: Clojure 性能 tips(翻譯)  回復  更多評論   

    2014-01-23 09:32 by Syeerzy
    在我的筆記本電腦上測試, 性能比上面的數字平均大約高 200 倍左右.
    而且(注意我改了數字,我的重復次數是上文的100倍)

    user=> (time (dotimes [_ 1e9] (+ 2 4 5)))
    "Elapsed time: 318.793 msecs"
    nil
    user=> (time (dotimes [_ 1e9] (+ 2 (+ 4 5))))
    "Elapsed time: 322.425 msecs"
    nil
    user=> (time (dotimes [i 1e9] (== i i)))
    "Elapsed time: 315.532 msecs"
    nil
    user=> (time (dotimes [i 1e9] (= i i)))
    "Elapsed time: 316.966 msecs"
    nil

    強制設置類型,使用二元運算符,使用==代替= 等操作幾乎沒有帶來可以觀察到的性能提升,而不是文中說的幾十倍.

    另外,避免vectors的destructing binding實測提升性能70%左右(而不是文中的20幾倍)
    優先使用本地變量實測提升性能20%-30%(而不是文中的12倍)


    基本上所有文中說的提升性能的操作都是不劃算的. 此文有嚴重誤導傾向. 所有測試都照文中給的代碼, 并且測試20次以上.

    # re: Clojure 性能 tips(翻譯)  回復  更多評論   

    2014-02-13 22:50 by steven.cui
    @Syeerzy
    具體性能提高多少可能跟jvm版本以及clj版本有區別,這個應該還是在clojure1.3之前的文章,現在的版本估計已經足夠聰明了,還是那句話過度優化和過早優化都是惡魔。@Syeerzy

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产国产人免费视频成69大陆| 亚洲精品NV久久久久久久久久| heyzo亚洲精品日韩| 亚洲人成在线电影| 亚洲av午夜国产精品无码中文字 | 成人午夜免费视频| 久久精品人成免费| 免费人成在线观看播放国产| 亚洲日本中文字幕区| 午夜亚洲国产精品福利| 中文字幕在线免费观看| 亚洲不卡AV影片在线播放| 亚洲最大视频网站| AAAAA级少妇高潮大片免费看| 特级做A爰片毛片免费69| 不卡精品国产_亚洲人成在线| 亚洲已满18点击进入在线观看| 91视频免费观看高清观看完整| 成人毛片手机版免费看| 亚洲AV无码AV男人的天堂| 男女超爽视频免费播放| 国产四虎免费精品视频| 亚洲中文字幕无码久久综合网| 亚洲AV无码成人精品区狼人影院| 很黄很污的网站免费| 免费人妻av无码专区| 97久久国产亚洲精品超碰热| 久久狠狠躁免费观看2020| 亚洲性在线看高清h片| 亚洲熟女www一区二区三区| 亚洲视频免费在线看| 亚洲精品无码久久千人斩| 国产亚洲精品2021自在线| 毛片免费全部免费观看| 日木av无码专区亚洲av毛片| 成人妇女免费播放久久久| 免费大片在线观看网站| 亚洲欧洲无码AV不卡在线| 日韩免费精品视频| 亚洲精品欧洲精品| 毛片无码免费无码播放|