2013-04-02 24 views
0

我如何能捕捉一個Haskell功能的運行,例如,文件Main.hs,包含一個函數「冒泡」,這在列表中的項目進行排序GHC編譯:哈斯克爾獲取函數運行時間

bubbleSort :: (Ord t) => [t] -> [t] 
bubbleSort a = loop (length a) bubble a 

bubble :: (Ord t) => [t] -> [t] 
bubble (a:b:c) | a < b = a : bubble (b:c) 
     | otherwise = b : bubble (a:c) 
bubble (a:[]) = [a] 
bubble [] = [] 

loop :: (Num a, Ord a) => a -> (t -> t) -> t -> t 
loop num f x | num > 0 = loop (num-1) f x' 
    | otherwise = x 
    where x' = f x 

注意:我知道這不是最有效的排序方法。

回答

3

你可以嘗試這樣的標準,

import System.Random 
import Data.List 
import Criterion.Main 
import Criterion.Config 


bubbleSort :: (Ord t) => [t] -> [t] 
bubbleSort a = loop (length a) bubble a 

loop :: (Num a, Ord a) => a -> (t -> t) -> t -> t 
loop num f x 
    | num > 0 = loop (num-1) f x' 
    | otherwise = x 
     where x' = f x 

bubble :: (Ord t) => [t] -> [t] 
bubble (a:b:c) | a < b = a : bubble (b:c) 
       | otherwise = b : bubble (a:c) 
bubble (a:[]) = [a] 
bubble [] = [] 

randomlist :: Int -> StdGen -> [Int] 
randomlist n = take n . unfoldr (Just . random) 

main = do 
    seed <- newStdGen 
    let 
     xs100 = randomlist 100 seed 
     xs500 = randomlist 500 seed 
     xs2500 = randomlist 2500 seed 
     in defaultMainWith defaultConfig (return()) [ 
      bgroup "bubble" [ 
       bench "bubble 100" $ nf bubble xs100 
       , bench "bubble 500" $ nf bubble xs500 
       , bench "bubble 2500" $ nf bubble xs2500 
       ], 
      bgroup "bubble Sort" [ 
       bench "bubbleSort 100" $ nf bubbleSort xs100 
       , bench "bubbleSort 500" $ nf bubbleSort xs500 
       , bench "bubbleSort 2500" $ nf bubbleSort xs2500 
       ] 
      ] 

和輸出,

warming up 
estimating clock resolution... 
mean is 2.181457 us (320001 iterations) 
found 41466 outliers among 319999 samples (13.0%) 
    2428 (0.8%) low severe 
    39038 (12.2%) high severe 
estimating cost of a clock call... 
mean is 105.7764 ns (13 iterations) 

benchmarking bubble/bubble 100 
mean: 5.174493 us, lb 5.158926 us, ub 5.190592 us, ci 0.950 
std dev: 80.64570 ns, lb 70.99540 ns, ub 93.12886 ns, ci 0.950 
variance introduced by outliers: 8.479% 
variance is slightly inflated by outliers 

benchmarking bubble/bubble 500 
mean: 28.41568 us, lb 28.22828 us, ub 28.64927 us, ci 0.950 
std dev: 1.071815 us, lb 843.6888 ns, ub 1.531296 us, ci 0.950 
found 4 outliers among 100 samples (4.0%) 
    2 (2.0%) high mild 
    1 (1.0%) high severe 
variance introduced by outliers: 34.577% 
variance is moderately inflated by outliers 

benchmarking bubble/bubble 2500 
mean: 132.3620 us, lb 131.0149 us, ub 134.1072 us, ci 0.950 
std dev: 7.802474 us, lb 6.333342 us, ub 11.58801 us, ci 0.950 
found 1 outliers among 100 samples (1.0%) 
    1 (1.0%) high severe 
variance introduced by outliers: 56.487% 
variance is severely inflated by outliers 

benchmarking bubble Sort/bubbleSort 100 
mean: 399.7690 us, lb 398.7208 us, ub 400.7847 us, ci 0.950 
std dev: 5.291009 us, lb 4.761788 us, ub 5.961798 us, ci 0.950 
variance introduced by outliers: 6.563% 
variance is slightly inflated by outliers 

benchmarking bubble Sort/bubbleSort 500 
mean: 15.42273 ms, lb 15.26078 ms, ub 15.60196 ms, ci 0.950 
std dev: 872.8984 us, lb 784.0365 us, ub 967.8269 us, ci 0.950 
variance introduced by outliers: 54.470% 
variance is severely inflated by outliers 

benchmarking bubble Sort/bubbleSort 2500 
collecting 100 samples, 1 iterations each, in estimated 48.56091 s 
mean: 473.5322 ms, lb 472.0005 ms, ub 474.9877 ms, ci 0.950 
std dev: 7.695022 ms, lb 6.700990 ms, ub 9.001423 ms, ci 0.950 
found 2 outliers among 100 samples (2.0%) 
    2 (2.0%) low mild 
variance introduced by outliers: 9.408% 
variance is slightly inflated by outliers 
+0

不客氣! – zurgl

+0

對於'bubbleSort',確實'whnf'就足夠了。但對於「泡沫」來說,它只會強制進行一次比較(也可能是交換)。通常,當使用列表結果對基準函數進行基準測試時,您需要'nf'。 –

+0

爲什麼「在估計29.32801秒內收集100個樣本,每次迭代100次」只出現一次,在「基準化氣泡排序/ bubbleSort 2500」下出現?奇怪的...... –

0

最簡單,最複雜的方法是,先編譯ghc --make yourfile.hs您的文件,然後在你的shell中運行它命令提示符爲> yourfile +RTS -s並檢查統計信息打印輸出。

文件應先從

{-# OPTIONS_GHC -O2 #-} 

module Main 
where 

,幷包含IO()類型的一個main值,例如

main :: IO() 
main = print $ bubbleSort ([1..50]++[42]) 

要想從本任何有意義的閱讀,你應該找出empirical orders of growth您算法;只有一個數據點不會告訴你很多。

+0

有什麼辦法讓它進入更詳細的時間測量?例如,如果時間不到一秒? – user2214957

+0

@ user2214957你可以運行它10或100次,並通過你的shell(無-RTS + s)來運行它;或增加數據的大小以實現更長的執行時間。這就是我所說的「最不復雜的」...... :) –