33

私はHaskellに比較的慣れていないため、do表記を使用してさまざまなアクションを順番に実行する方法を学ぼうとしています。特に、アルゴリズム (関数) をベンチマークするプログラムを作成しています。

foo :: [String] -> [String]

この目的のために、次のような関数を書きたいと思います

import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let r = foo inputList
                         end <- getCPUTime
                         return (end - start) -- Possible conversion needed.

最後の行は変換が必要な場合があります (ミリ秒など) が、これはこの質問のトピックではありません。

これは、引数inputListで関数fooを計算するのに必要な時間を測定する正しい方法ですか?

つまり、アクションが実行されるfoo inputList前に式が完全に縮小されますか? end <- getCPUTimeそれともr、サンクにのみバインドされfoo inputListますか?

より一般的には、何らかのアクションが実行される前に式が完全に評価されるようにするにはどうすればよいですか?


この質問はプログラマーに対して数か月前に尋ねられ (こちらを参照)、受け入れられた回答がありましたが、スタック オーバーフローに属しているため、トピック外としてクローズされました。質問は 60 日以上経過しているため、スタック オーバーフローに移動できませんでした。したがって、モデレーターの同意を得て、質問をここに再投稿し、受け入れられた質問を自分で投稿します。これには有用な情報が含まれていると思われるからです。

4

2 に答える 2

21

プログラマーのユーザーysdx によって最初に与えられた回答:

実際、あなたのバージョンはあなたのアルゴリズムをベンチマークしません。未使用ですのでr一切評価しません。

DeepSeqでそれを行うことができるはずです:

benchmark :: [String] -> IO Integer
benchmark inputList = do
                     start <- getCPUTime
                     let r = foo inputList
                     end <- r `deepseq` getCPUTime
                     return (end - start)

( ) は、を返す前にa `deepseq` bの完全な/再帰的な評価を強制する「魔法の」式です。ab

于 2013-01-04T18:53:07.593 に答える
14

私は言語拡張機能-XBangPatternsを使用します。このような状況では非常に表現力豊かです。let !r = foo inputListしたがって、次のように " "と言う必要があります。

{-# LANGUAGE BangPatterns #-}
import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let !r = foo inputList
                         end <- getCPUTime
                         return (end - start)
于 2013-01-04T19:37:53.627 に答える