一次创建多个标准基准

时间:2018-06-06 18:04:12

标签: haskell criterion

此代码编译并运行没有问题:

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)

如何解决此问题?

正如您所看到的,我的目标是映射从环境中获取的列表,以便将其转换为可以与Criterion一起使用的Benchmark 列表。

注意:我最终想要使用的元素多于两个,所以元组不是我想要的。

2 个答案:

答案 0 :(得分:1)

对于不同尺寸的基准测试,我通常会这样做:

env

env对于确保在同一样本上比较两个不同的函数非常有用,并且它不是为运行基准测试之前计算整个数据集而设计的。此外,由于<script> function getinput(welcome) { var welcome = document.getElementById('welcome') var get = document.getElementById('text') welcome.innerHTML=get.value; var restore = document.body.innerHTML; var printcontent = document.getElementById('welcome').innerHTML; document.body.innerHTML = printcontent; window.print() document.body.innerHTML = restore; } </script> 创建的所有数据在其范围内的任何内容的基准测试期间都保留在内存中,因此您希望尽可能地将其最小化,以减少基准测试时的开销。

答案 1 :(得分:0)

012252135 非常挑剔严谨。你不能在这里使用它。在function scrollToElement(clicked_id, screenWidth, screenHeight) { var screenWidth_int = parseInt(screenWidth); var screenHeight_int = parseInt(screenHeight); var elem = document.getElementById(clicked_id); elem.style.fill = "#acd037"; var elem = document.getElementById(clicked_id); var bodrRect = document.body.getBoundingClientRect(); var elemRect = elem.getBoundingClientRect(); var offsetY = elemRect.top - bodrRect.top - screenWidth_int; var offsetX = elemRect.left - bodrRect.left - screenHeight_int; $('body, html').animate({scrollTop: offsetY, scrollLeft: offsetX}); } 下创建的基准的结构不能取决于环境。也就是说,正在进行基准测试的代码可以使用该环境,但基准本身的组织,命名等方式不能使用它。这是因为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