这段代码编译和运行都没有问题:
module Main where
import Criterion.Main
main :: IO ()
main =
defaultMain
[env (return $ [1,2])
(\is ->
bgroup "group" (benchmarks is))]
timesTwo :: Int -> Int
timesTwo i = 2 * i
benchmarks :: [Int] -> [Benchmark]
benchmarks is = [ bench "foo" $ nf timesTwo (is !! 0)
, bench "foo" $ nf timesTwo (is !! 1) ]
但是,如果我将benchmarks
函数改为如下所示
benchmarks :: [Int] -> [Benchmark]
benchmarks is = map (\i -> bench "foo" $ nf timesTwo i) is
它仍然可以编译,但我得到了这个运行时错误:
ghci> main
*** Exception: Criterion atttempted to retrieve a non-existent environment!
Perhaps you forgot to use lazy pattern matching in a function which
constructs benchmarks from an environment?
(see the documentation for `env` for details)
我该如何解决这个问题?
正如您所看到的,我的目标是映射从环境中获得的列表,以便将其转换为我可以与Benchmark
**s**一起使用的列表。
注意:我最终希望使用比两个元素多得多的元素,所以我不想在这里使用元组。
发布于 2018-06-07 07:25:49
对于不同规模的基准测试,我通常这样做:
module Main (main) where
import Criterion.Main
import System.Random
import Control.Monad
import qualified Data.List
import qualified Data.Sequence
int :: Int -> IO Int
int n = randomRIO (0,n)
benchAtSize :: Int -> Benchmark
benchAtSize n =
env (replicateM n (int n)) $
\xs ->
bgroup (show n)
[ bench "Data.List" $ nf Data.List.sort xs
, bench "Data.Sequence" $ nf (Data.Sequence.sort . Data.Sequence.fromList) xs
]
main :: IO ()
main = defaultMain (map benchAtSize [100, 1000, 10000])
env
对于确保在同一个样本上比较两个不同的函数很有用,而且它不是为了在运行基准测试之前计算整个数据集而设计的。此外,由于在对其作用域内的任何内容进行基准测试期间,env
创建的所有数据都保存在内存中,因此您希望尽可能地将其最小化,以减少基准测试时的开销。
发布于 2018-06-07 02:40:30
env
非常挑剔,非常严格。你不能在这里使用它。在env
下创建的基准测试的结构不能依赖于环境。也就是说,环境可以由正在进行基准测试的代码使用,但是基准测试本身的组织、命名等方式不能使用它。这是因为当criterion
只想检查基准测试的结构而不执行它们时,它有时会传递_|_
而不是实际环境。使用!!
时,即使在使用is = _|_
时,基准的组织也是手工给出的,并且保持不变
benchmarks _|_ = [ bench "foo" $ nf timesTwo _|_ -- _|_ !! n = _|_; nf is not strict
, bench "foo" $ nf timesTwo _|_ ] -- "bench"s are still there
但map
打破了这一点:
benchmarks _|_ = map _etc _|_
= case _|_ of -- definition of map
[] -> []
x:xs -> _etc x : map _etc xs
= _|_ -- benchmark structure gone
你最好的选择就是不使用env
main = do is <- _ -- however you calculate is
defaultMain $ bgroup "group" $ benchmark is
https://stackoverflow.com/questions/50726837
复制相似问题