自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Clojure世界:如何做性能測試

運(yùn)維 系統(tǒng)運(yùn)維
我們經(jīng)常需要在程序中測量某段代碼的性能,或者某個(gè)函數(shù)的性能,在Java中,我們可能簡單地循環(huán)調(diào)用某個(gè)方法多少次,然后利用System.currentTimeMillis()方法測量下時(shí)間。在Ruby中,一般都是用Benchmark module做測試,提供了更詳細(xì)的報(bào)告信息。

我們經(jīng)常需要在程序中測量某段代碼的性能,或者某個(gè)函數(shù)的性能,在Java中,我們可能簡單地循環(huán)調(diào)用某個(gè)方法多少次,然后利用System.currentTimeMillis()方法測量下時(shí)間。在Ruby中,一般都是用Benchmark module做測試,提供了更詳細(xì)的報(bào)告信息。

 
    同樣,在Clojure里你可以做這些事情,你仍然可以使用System.currentTimeMillis()來測量運(yùn)行時(shí)間,例如:
 
 
user=> (defn sum1 [& args] (reduce + 0 args))
#'user/sum1
 
user=> (defn sum2 [& args]
             (loop [rt 0
                    args args]
                 (if args
                   (recur (+ rt (first args)) (next args))
                   rt)))
#'user/sum2
 
user=> (defn bench [sum n]
         (let [start (System/currentTimeMillis)
               nums (range 0 (+ n 1))]
           (dotimes [_ n] (apply sum nums))
           (println (- (System/currentTimeMillis) start))))
 
user=> (bench sum1 10000)
1818
nil
user=> (bench sum2 10000)
4220
nil
   
    定義兩個(gè)求和函數(shù)sum1和sum2,一個(gè)是利用reduce,一個(gè)是自己寫loop,然后寫了個(gè)bench函數(shù)循環(huán)一定次數(shù)執(zhí)行sum函數(shù)并給出執(zhí)行時(shí)間,利用System.currentTimeMillis()方法。顯然sum1比sum2快了一倍多。為什么更快?這不是我們的話題,有興趣可以自己看reduce函數(shù)的實(shí)現(xiàn)。
 
    除了用System.currentTimeMillis()這樣的java方式測量運(yùn)行時(shí)間外,clojure還提供了time宏來包裝這一切:
 
user=> (doc time)
-------------------------
clojure.core/time
([expr])
Macro
  Evaluates expr and prints the time it took.  Returns the value of
 expr.
nil
 
    time宏用的不是currentTimeMillis方法,而是JDK5引入的nanoTime方法更精確。重寫bench函數(shù):
 
user=> (defn bench [sum n]
             (time (dotimes [_ n] (apply sum (range 0 (+ n 1))))))
#'user/bench
 
user=> (bench sum1 10000)
"Elapsed time: 5425.074 msecs"
nil
user=> (bench sum2 10000)
"Elapsed time: 7893.412 msecs"
nil
     盡管精度不一致,仍然可以看出來sum1比sum2快。
    
     這樣的測試仍然是比較粗糙的,真正的性能測試需要考慮到JVM JIT、warm up以及gc帶來的影響,例如我們可能需要預(yù)先執(zhí)行函數(shù)多少次來讓JVM“預(yù)熱”這些代碼。慶幸的是clojure世界里有一個(gè)開源庫Criterium幫你自動(dòng)搞定這一切,它的項(xiàng)目主頁也在github上:https://github.com/hugoduncan/criterium 
 
     首先在你的項(xiàng)目里添加criterium依賴:
 
:dependencies [[org.clojure/clojure "1.3.0"]
                        [criterium "0.2.0"]])
   
     接下來引用criterium.core這個(gè)ns,因?yàn)閏riterium主要宏也叫bench,因此我們原來的bench函數(shù)不能用了,換個(gè)名字叫bench-sum:
 
user=> (use 'criterium.core)
nil
user=> (defn bench-sum [sum n]
              (with-progress-reporting (bench (apply sum (range 0 (+ 1 n))) :verbose)))
#'user/bench-sum
 
     調(diào)用criterium的bench宏執(zhí)行測試,使用with-progress-reporting宏包裝測試代碼并匯報(bào)測試進(jìn)展,測試進(jìn)展會打印在標(biāo)準(zhǔn)輸出上。請注意,我這里并沒有利用dotimes做循環(huán)測試,因?yàn)閏riterium會自己計(jì)算應(yīng)該運(yùn)行的循環(huán)次數(shù),我們并不需要明確指定,測試下結(jié)果:
 
user=> (bench-sum sum1 10000)
Cleaning JVM allocations 
Warming up for JIT optimisations 
Estimating execution count 
Running with sample-count 60 exec-count 1417 
Checking GC
Cleaning JVM allocations 
Finding outliers 
Bootstrapping 
Checking outlier significance
x86_64 Mac OS X 10.7.3 4 cpu(s)
Java HotSpot(TM) 64-Bit Server VM 20.4-b02-402
Runtime arguments: -Dclojure.compile.path=/Users/apple/programming/avos/logdashboard/test/classes -Dtest.version=1.0.0-SNAPSHOT -Dclojure.debug=false
Evaluation count             : 85020
             Execution time mean : 722.730169 us  95.0% CI: (722.552670 us, 722.957586 us)
    Execution time std-deviation : 1.042966 ms  95.0% CI: (1.034972 ms, 1.054015 ms)
         Execution time lower ci : 692.122089 us  95.0% CI: (692.122089 us, 692.260198 us)
         Execution time upper ci : 768.239944 us  95.0% CI: (768.239944 us, 768.305222 us)
 
Found 2 outliers in 60 samples (3.3333 %)
    low-severe     2 (3.3333 %)
 Variance from outliers : 25.4066 % Variance is moderately inflated by outliers
nil
 
 
user=> (bench-sum sum2 10000)
Cleaning JVM allocations 
Warming up for JIT optimisations 
Estimating execution count 
Running with sample-count 60 exec-count 917 
Checking GC
Cleaning JVM allocations 
Finding outliers 
Bootstrapping 
Checking outlier significance
x86_64 Mac OS X 10.7.3 4 cpu(s)
Java HotSpot(TM) 64-Bit Server VM 20.4-b02-402
Runtime arguments: -Dclojure.compile.path=/Users/apple/programming/avos/logdashboard/test/classes -Dtest.version=1.0.0-SNAPSHOT -Dclojure.debug=false
Evaluation count             : 55020
             Execution time mean : 1.070884 ms  95.0% CI: (1.070587 ms, 1.071136 ms)
    Execution time std-deviation : 1.057659 ms  95.0% CI: (1.050688 ms, 1.062877 ms)
         Execution time lower ci : 1.024195 ms  95.0% CI: (1.024164 ms, 1.024195 ms)
         Execution time upper ci : 1.145664 ms  95.0% CI: (1.145664 ms, 1.145741 ms)
 
Found 1 outliers in 60 samples (1.6667 %)
    low-severe     1 (1.6667 %)
 Variance from outliers : 19.0208 % Variance is moderately inflated by outliers
nil
 
 
    這個(gè)報(bào)告是不是相當(dāng)專業(yè)?不是搞統(tǒng)計(jì)還不一定讀的懂。大概解讀下,sample-count是取樣次數(shù),默認(rèn)是60次,exec-count是測試的執(zhí)行次數(shù)(不包括前期warm up和JIT在內(nèi)),CI是可信區(qū)間,這里取95%,Execution time mean是平均執(zhí)行時(shí)間,而lower和upper是測試過程中執(zhí)行時(shí)間的最小和最大值。而outliers是這一組測試中的異常值,比如執(zhí)行sum1測試發(fā)現(xiàn)了2組異常結(jié)果。從結(jié)果來看,sum1的平均執(zhí)行時(shí)間是722微秒,而sum2的平均執(zhí)行時(shí)間是1.07毫秒,因此還是sum1更快一些。
 
    總結(jié)下,如果只是在開發(fā)過程中做一些小塊代碼的簡單測試,可以直接利用內(nèi)置的time宏,如果你希望做一次比較標(biāo)準(zhǔn)的性能測試,那么就應(yīng)該利用criterium這個(gè)優(yōu)秀的開源庫。

【編輯推薦】

  1. 獵豹瀏覽器初體驗(yàn)
  2. Windows安全最高境界
  3. IE8安全新功能實(shí)測,到底給不給力?
責(zé)任編輯:趙寧寧
相關(guān)推薦

2022-08-03 09:11:31

React性能優(yōu)化

2012-03-12 16:42:54

測試

2021-09-18 15:40:03

Vue單元測試命令

2020-10-12 10:20:07

軟件測試 技術(shù)

2025-03-31 01:55:00

2019-09-15 14:07:49

2013-08-26 15:09:23

互聯(lián)網(wǎng)測試

2011-03-01 10:42:23

無線局域網(wǎng)局域網(wǎng)性能優(yōu)化

2021-05-13 08:00:00

軟件測試程序IT

2024-07-10 08:26:02

開源項(xiàng)目測試

2022-05-26 10:19:59

k6性能測試

2017-11-16 21:21:18

DevOps測試軟件開發(fā)

2022-08-29 08:08:58

SQLOracleCPU

2023-12-29 08:29:15

QPS系統(tǒng)應(yīng)用

2015-07-30 11:21:16

代碼審查

2023-12-29 10:04:47

數(shù)據(jù)分析

2022-02-17 13:18:58

定價(jià)模型營銷AHP

2016-09-21 10:18:26

阿里Dubbo性能測試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號