下面是使用自定義主要的解決方案通過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*
函數被調用一次,不影響基準結果。
AFAIU,要求在兩個基準之間進行清理。 –
因此我的第二個選擇。如果這裏有合法的全局狀態,那麼在每個'theFirst >> cleanUpTheFirst'之前'initTheFirst'都是必需的,但在使用defaultMain時,我沒有看到這兩個選項之一的替代方案。 –
不幸的是我無法使用第一個選項。重新選擇第二個選項:你的意思是從總運行時間替換init/cleanup對的運行時間嗎?由於初始化/清理運行時間的變化(它很重),會不會導致結果無效? – Yuras