4

内のいくつかのコードをベンチマークする必要がありIO、基準はそれをかなりうまくサポートしています。しかし、いくつかの初期化手順を実行したいと考えています (ベンチマークごとに異なります)。単純なアプローチ:

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

ただし、ベンチマークの実行ごとに初期化とクリーンアップを実行し (デフォルトでは 100 回)、最終結果までの初期化時間を含みます。初期化時間を除外することはできますか?

追加: コードはグローバル状態 (実際には mongodb) を使用するため、2 つの初期状態を同時に準備することはできません。

4

2 に答える 2

5

argiopeweb が提案するカスタム main を使用したソリューションを次に示します。

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*関数が 1 回だけ呼び出され、ベンチマークの結果に影響を与えないことがわかります。

于 2013-10-02T19:22:04.057 に答える
2

ここで見ることができる 3 つの実際のオプション。前後に初期化とクリーンアップを行います。

main = do
  initTheFirst
  initTheSecond

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

  cleanUpTheFirst
  cleanUpTheSecond

または、それが不可能な場合は、クリーンアップと初期化のプロセスもベンチマークし、それに応じてベンチマーク時間を変更します。

defaultMainまたは、提供されている を使用するのをやめて、代わりに Criterion が提供する低レベルの関数を使用して独自のものを作成することもできます。

于 2013-10-02T15:54:33.937 に答える