私はバイナリ検索ツリーでN番目に小さい番号を見つける2つの実装の性能を比較しようとしています。これは単なるおもちゃの学習問題です。測定での私のナイーブの試みは、次のとおりです。単純なHaskellパフォーマンス解析
私は私がそれをしたい怠惰を含め、私がいないところ、それを防ぐ方法を考え出す苦労していますgetNth :: Tree Int -> Int -> Either String Int
eval :: [Either b Int] -> Int
eval = (foldl (+) 0) . rights
main :: IO()
main = do
let t = foldl treeInsertBalanced EmptyTree [1..1000000]
first = getNth t 100000
iterations = 100000000000
second = take iterations $ repeat $ getNth t 100
third = take iterations $ repeat $ getNth' t 100
print $ "dummy to cause eval: " ++ (show first)
print ""
time1 <- System.CPUTime.getCPUTime
print $ eval second
time2 <- System.CPUTime.getCPUTime
print $ eval third
time3 <- System.CPUTime.getCPUTime
let secondTime = time2-time1
thirdTime = time3-time2
timeDiff = secondTime - thirdTime
print $ "take version = " ++ (show secondTime)
print $ "opt version = " ++ (show thirdTime)
print $ "diff = " ++ (show timeDiff)
。
ツリーを完全に構築してから、そのツリーで操作する関数の測定を開始します。このため、getNthを呼び出して印刷することで、tの評価を強制しようとしています。
- これは私が望んでいることをやっているのですか?
- 後で使用すると完全に評価されます。
2つのgetNth関数の実装の違いは、ツリーの単純な深さの最初の検索で最初の関数が 'take'関数を使用することです。 2番目の方法は明示的な早期リターンで深さの最初の検索を行います。シンプルな「テイク」の実装がツリー全体を歩かなければならないかどうかを知りたい。どのようにすれば、2つの機能の性能を測定するより簡単な方法でそれを判断できますか。ツリー内の値として「エラー」または「未定義」を導入しようとしましたが、ツリーのN番目の要素でない限り評価されませんでした。 getNth関数が本当に怠惰であるかどうかを判断する別の簡単な方法はありますか? (http://pastebin.com/jpg0vSNdで.lhsとして入手可能)
基準などのベンチマークパッケージを使用することを検討してください。 –