首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >一次创建多个标准基准

一次创建多个标准基准
EN

Stack Overflow用户
提问于 2018-06-07 02:04:12
回答 2查看 241关注 0票数 3

这段代码编译和运行都没有问题:

代码语言:javascript
复制
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函数改为如下所示

代码语言:javascript
复制
benchmarks :: [Int] -> [Benchmark]
benchmarks is = map (\i -> bench "foo" $ nf timesTwo i) is

它仍然可以编译,但我得到了这个运行时错误:

代码语言:javascript
复制
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**一起使用的列表。

注意:我最终希望使用比两个元素多得多的元素,所以我不想在这里使用元组。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-07 07:25:49

对于不同规模的基准测试,我通常这样做:

代码语言:javascript
复制
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创建的所有数据都保存在内存中,因此您希望尽可能地将其最小化,以减少基准测试时的开销。

票数 2
EN

Stack Overflow用户

发布于 2018-06-07 02:40:30

env非常挑剔,非常严格。你不能在这里使用它。在env下创建的基准测试的结构不能依赖于环境。也就是说,环境可以由正在进行基准测试的代码使用,但是基准测试本身的组织、命名等方式不能使用它。这是因为当criterion只想检查基准测试的结构而不执行它们时,它有时会传递_|_而不是实际环境。使用!!时,即使在使用is = _|_时,基准的组织也是手工给出的,并且保持不变

代码语言:javascript
复制
benchmarks _|_ = [ bench "foo" $ nf timesTwo _|_ -- _|_ !! n = _|_; nf is not strict
                 , bench "foo" $ nf timesTwo _|_ ] -- "bench"s are still there

map打破了这一点:

代码语言:javascript
复制
benchmarks _|_ = map _etc _|_
               = case _|_ of -- definition of map
                      [] -> []
                      x:xs -> _etc x : map _etc xs
               = _|_ -- benchmark structure gone

你最好的选择就是不使用env

代码语言:javascript
复制
main = do is <- _ -- however you calculate is
          defaultMain $ bgroup "group" $ benchmark is
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50726837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档