标签: haskell-criterion

基准测试过滤器和分区

我认为,我正在测试partition列表函数的性能并得到一些奇怪的结果.

我们有,partition p xs == (filter p xs, filter (not . p) xs)但我们选择了第一个实现,因为它只对列表执行单次遍历.然而,我得到的结果表明,使用使用两次遍历的实现可能更好.

这是显示我所看到的最小代码

import Criterion.Main
import System.Random
import Data.List (partition)

mypartition :: (a -> Bool) -> [a] -> ([a],[a])
mypartition p l = (filter p l, filter (not . p) l)



randList :: RandomGen g => g -> Integer -> [Integer]
randList gen 0 = []
randList gen n = x:xs
  where
    (x, gen') = random gen
    xs = randList gen' (n - 1)

main …
Run Code Online (Sandbox Code Playgroud)

haskell ghc haskell-criterion

18
推荐指数
1
解决办法
325
查看次数

如何使用Criterion来衡量Haskell程序的性能?

我正在尝试使用Criterion框架来衡量一个简单的Haar DWT程序的性能.(这是错误的慢,但我会留下另一个问题).遗憾的是,我无法在网上找到任何好的文档.我的两个主要问题是

  • 如何将数据从一个基准传递到另一个?我想计划该计划的每个阶段.
  • 采样如何工作,并避免延迟评估重用其先前的计算?

这个来源相对减少了; 第一个函数getRandList生成一个随机数列表; haarStep将输入信号转换为差值和求和,并haarDWT调用前者并对求和进行递归.我试图传递getRandListhaarDWT通过懒惰的评价,但也许我的使用是不正确/不支持.时间似乎没有意义.

{-# LANGUAGE ViewPatterns #-}

import Control.Arrow
import qualified Data.Vector.Unboxed as V
import System.Random
import Criterion.Main

invSqrt2 = 0.70710678118654752440

getRandList :: RandomGen g => g -> Int -> [Float]
getRandList gen 0 = []
getRandList gen n = v:rest where
    (v, gen') = random gen
    rest = getRandList gen' (n - 1)

haarStep :: V.Vector Float -> (V.Vector Float, V.Vector Float)
haarStep = (alternatingOp (-) …
Run Code Online (Sandbox Code Playgroud)

performance haskell haskell-criterion

15
推荐指数
1
解决办法
2353
查看次数

如何可靠地比较Haskell和C的运行时?

我使用Criterion库为我的Haskell函数编写基准.现在我在C中实现相同的算法来比较Haskell的性能.问题是如何可靠地做到这一点?Criterion做了很多花哨的事情,例如计算时钟调用开销和对结果进行统计分析.我想如果我只是测量我的C函数所需的时间,它将无法与Criterion返回的结果进行比较.在他关于Criterion的原始帖子中, Bryan O'Sullivan写道:"使用标准对C代码和命令行程序进行基准测试应该很容易." 问题是如何?Takayuki Muranushi 比较了DFT的C实现使用Haskell生成线程并调用可执行文件,但我担心这会增加很多额外的开销(创建新线程,运行应用程序,输出到stdio然后从中读取),这使得结果无法比拟.我也考虑使用FFI,但我再次担心额外的开销会使这种比较不公平.

如果没有办法使用Criterion可靠地对C进行基准测试,那么您会推荐哪种C基准测试方法?我在这里读过一些关于SO的问题,似乎有许多不同的函数可以测量系统时间,但是它们要么以毫秒为单位提供时间,要么有大量的调用开销.

c benchmarking haskell haskell-criterion

14
推荐指数
1
解决办法
965
查看次数

如何获得一致的标准基准,或跨运行解释结果?

我正在尝试优化一些代码,使用标准来尝试比较,例如,将INLINEpragma 添加到函数的效果.但我发现重新编译/运行之间的结果并不一致.

我需要知道如何使结果在运行中保持一致,以便我可以比较它们,或者如何评估基准是否可靠,即(我猜)如何解释方差的细节,"成本时钟呼叫"等

我的具体案例详情

这与我上面的主要问题是正交的,但是在我的特定情况下,有几件事可能导致不一致:

  1. 我正在尝试使用基准测试IO操作,whnfIO因为whnf此示例中使用的方法不起作用.

  2. 我的代码使用并发

  3. 我有很多标签和垃圾打开

示例输出

这两个都来自相同的代码,以完全相同的方式编译.我直接在下面进行了第一次运行,做了一个更改并做了另一个基准测试,然后还原并再次运行第一个代码,编译:

ghc --make -fforce-recomp -threaded -O2 Benchmark.hs
Run Code Online (Sandbox Code Playgroud)

第一次运行:

estimating clock resolution...                                      
mean is 16.97297 us (40001 iterations)                              
found 6222 outliers among 39999 samples (15.6%)                     
  6055 (15.1%) high severe                                          
estimating cost of a clock call...                                  
mean is 1.838749 us (49 iterations)                                 
found 8 outliers among 49 samples (16.3%)                           
  3 (6.1%) high mild                                                
  5 (10.2%) high severe                                             

benchmarking actors/insert 1000, query 1000                         
collecting …
Run Code Online (Sandbox Code Playgroud)

benchmarking haskell haskell-criterion

13
推荐指数
2
解决办法
1012
查看次数

GHC中的交叉模块优化

我有一个非递归函数来计算似乎表现良好的最长公共子序列(ghc 7.6.1-O2 -fllvm标志编译),如果我Criterion在同一模块中测量它.在另一方面,如果我转换功能为模块,只导出功能(如建议在这里),然后用标准重新测量,我得到〜2倍放缓(这会消失,如果我移动的标准测回模块其中定义了函数).我尝试用INLINEpragma 标记函数,这对跨模块性能测量没有任何影响.

在我看来,GHC可能正在进行严格性分析,当函数和main(函数可以从中访问)位于同一模块中时,它可以很好地工作,但是当它们被分割时则不行.我希望有关如何模块化函数的指针,以便在从其他模块调用时表现良好.有问题的代码太大了,无法在此处粘贴 - 如果您想尝试一下,可以在此处查看.我正在尝试做的一个小例子如下(使用代码片段):

-- Function to find longest common subsequence given unboxed vectors a and b
-- It returns indices of LCS in a and b
lcs :: (U.Unbox a, Eq a) => Vector a -> Vector a -> (Vector Int,Vector Int)
lcs a b | (U.length a > U.length b) = lcsh b a True
        | otherwise = lcsh a b False

-- …
Run Code Online (Sandbox Code Playgroud)

optimization performance haskell haskell-criterion

13
推荐指数
1
解决办法
533
查看次数

从标准生成HTML输出

有一个从输出HTML的一个很好的例子标准http://bos.github.com/criterion/.

哪个命令行选项用于生成此输出?

回答到一个相关的问题断言,这个输出退出,但它似乎不使用时,在命令行选项来显示--help.

haskell haskell-criterion

10
推荐指数
2
解决办法
1039
查看次数

如何为Criterion基准创建数据?

我使用标准来对我的Haskell代码进行基准测试.我正在做一些繁重的计算,我需要随机数据.我写了这样的主要基准文件:

main :: IO ()
main = newStdGen >>= defaultMain . benchmarks

benchmarks :: RandomGen g => g -> [Benchmark]
benchmarks gen =
   [
     bgroup "Group"
     [
       bench "MyFun" $ nf benchFun (dataFun gen)
     ]
   ]
Run Code Online (Sandbox Code Playgroud)

我在不同的模块中为它们保留基准和数据生成器:

benchFun :: ([Double], [Double]) -> [Double]
benchFun (ls, sig) = fun ls sig

dataFun :: RandomGen g => g -> ([Double], [Double])
dataFun gen = (take 5 $ randoms gen, take 1024 $ randoms gen)
Run Code Online (Sandbox Code Playgroud)

这有效,但我有两个问题.首先,生成基准中包含的随机数据所需的时间是多少?我发现了一个涉及该主题的问题,但说实话,我无法将其应用于我的代码.为了检查是否发生这种情况,我在IO monad中编写了一个替代版本的数据生成器.我将基准列表与main(称为生成器)放在一起,用< - 提取结果,然后将其传递给基准函数.我发现性能没有差别. …

haskell haskell-criterion

10
推荐指数
1
解决办法
970
查看次数

在不同大小的输入上运行Haskell基准测试

我经常想比较同一函数的多个实现的运行时性能.对于个人投入,标准是一个很好的工具.

但是,在不同的输入大小上绘制代码性能的简单方法是什么,例如,查看算法的复杂性?

理想情况下,我向库传递一个类型的值Benchmarkable r => [(String, Int -> r)],即依赖于大小的基准列表,库将自动为每个值找到合理的输入范围,并从中创建一个漂亮的图.

benchmarking haskell graph time-complexity haskell-criterion

9
推荐指数
1
解决办法
263
查看次数

Scala标准相当于

是否有Scala(或Java,我猜)相当于标准?我不仅仅是在讨论基准测试库:请查看HTML结果的标准.

benchmarking haskell scala haskell-criterion

8
推荐指数
1
解决办法
296
查看次数

标准库选取的命令行选项

我使用了库标准和cmdargs.

当我在没有cmdargs的情况下完全编译程序并运行它时,例如./prog --help然后我从标准中得到一些不需要的响应,关于可能的选项和运行次数等.

当我编译并运行它时,命令行选项首先被我的代码选中,然后按标准读取.Criterion然后报告并且错误告诉我选项--byte是未知的.我没有在标准文档中看到如何关闭或解决这个问题.有没有办法清除我读过它们的命令行选项?否则我需要使用例如CPUTime而不是标准,这对我来说是好的,因为我真的需要额外的功能和标准提供的数据.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable #-}

import System.Console.CmdArgs

data Strlen = Strlen {byte :: Int} deriving (Data, Typeable, Show)

strlen = cmdArgsMode $ Strlen {byte = def} &= summary "MessagePack benchmark v0.04"

main = do
  n <- cmdArgsRun strlen
  let datastring = take (byte n) $ randomRs ('a','z') (mkStdGen 3)
  putStrLn "Starting..."
  conn <- connect "192.168.35.62" 8081
  defaultMain [bench "sendReceive" $ whnfIO (mywl conn datastring)] 
Run Code Online (Sandbox Code Playgroud)

haskell haskell-criterion

7
推荐指数
1
解决办法
362
查看次数