2013-10-02 26 views
4

我需要對IO中的一些代碼進行基準測試,並且標準支持非常好。但是我想執行很少的初始化步驟(每個基準測試都不同)。簡易方法:在標準中初始化基準,並從結果中排除初始化時間

main = defaultMain 
    [ bench "the first" $ do 
     initTheFirst 
     theFirst 
     cleanUpTheFirst 
    , bench "the second" $ do 
     initTheSecond 
     theSecond 
     cleanUpTheSecond 
    ] 

但它爲每一個基準測試(100次默認)執行初始化和清理,包括初始化時間到最後的結果。可以排除初始化時間嗎?

添加: 該代碼使用全局狀態(實際上是mongodb),所以我不能同時準備兩個初始狀態。

回答

2

我可以在這裏看到三個實際選項。無論是初始化和清理前後:

main = do 
    initTheFirst 
    initTheSecond 

    defaultMain 
    [ bench "the first" theFirst 
    , bench "the second" theSecond 
    ] 

    cleanUpTheFirst 
    cleanUpTheSecond 

或者,如果這是不可能的,也是你基準清理和初始化過程,並相應地修改您的基準時間。

或者,您可以放棄使用提供的defaultMain,而是使用Criterion提供的較低級別的功能推出自己的產品。

+0

AFAIU,要求在兩個基準之間進行清理。 –

+0

因此我的第二個選擇。如果這裏有合法的全局狀態,那麼在每個'theFirst >> cleanUpTheFirst'之前'initTheFirst'都是必需的,但在使用defaultMain時,我沒有看到這兩個選項之一的替代方案。 –

+0

不幸的是我無法使用第一個選項。重新選擇第二個選項:你的意思是從總運行時間替換init/cleanup對的運行時間嗎?由於初始化/清理運行時間的變化(它很重),會不會導致結果無效? – Yuras

5

下面是使用自定義主要的解決方案通過argiopeweb的建議:

import Control.Monad 
import Control.Monad.IO.Class 
import Control.Concurrent 
import Criterion 
import Criterion.Config 
import Criterion.Monad 
import Criterion.Environment 

main :: IO() 
main = myMain [ 
    (initTheFirst, theFirst), 
    (initTheSecond, theSecond) 
    ] 

initTheFirst :: IO() 
initTheFirst = do 
    putStrLn "initializing the first" 
    threadDelay 1000000 

theFirst :: Benchmark 
theFirst = bench "the first" $ do 
    return() :: IO() 

initTheSecond :: IO() 
initTheSecond = do 
    putStrLn "initializing the second" 
    threadDelay 1000000 

theSecond :: Benchmark 
theSecond = bench "the second" $ do 
    return() :: IO() 

myMain :: [(IO(), Benchmark)] -> IO() 
myMain benchmarks = withConfig defaultConfig $ do 
    env <- measureEnvironment 
    forM_ benchmarks $ \(initialize, benchmark) -> do 
    liftIO $ initialize 
    runAndAnalyse (const True) env benchmark 

輸出:

warming up 
estimating clock resolution... 
mean is 1.723574 us (320001 iterations) 
found 1888 outliers among 319999 samples (0.6%) 
    1321 (0.4%) high severe 
estimating cost of a clock call... 
mean is 43.45580 ns (13 iterations) 
found 2 outliers among 13 samples (15.4%) 
    2 (15.4%) high severe 
initializing the first 

benchmarking the first 
mean: 7.782388 ns, lb 7.776217 ns, ub 7.790563 ns, ci 0.950 
std dev: 36.01493 ps, lb 29.29834 ps, ub 52.51021 ps, ci 0.950 
initializing the second 

benchmarking the second 
mean: 7.778543 ns, lb 7.773192 ns, ub 7.784518 ns, ci 0.950 
std dev: 28.85100 ps, lb 25.59891 ps, ub 32.85481 ps, ci 0.950 

你可以看到,init*函數被調用一次,不影響基準結果。

+0

這個答案值得被接受。 –