我认为,我正在测试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) 我正在尝试使用Criterion框架来衡量一个简单的Haar DWT程序的性能.(这是错误的慢,但我会留下另一个问题).遗憾的是,我无法在网上找到任何好的文档.我的两个主要问题是
这个来源相对减少了; 第一个函数getRandList
生成一个随机数列表; haarStep
将输入信号转换为差值和求和,并haarDWT
调用前者并对求和进行递归.我试图传递getRandList
给haarDWT
通过懒惰的评价,但也许我的使用是不正确/不支持.时间似乎没有意义.
{-# 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) 我使用Criterion库为我的Haskell函数编写基准.现在我在C中实现相同的算法来比较Haskell的性能.问题是如何可靠地做到这一点?Criterion做了很多花哨的事情,例如计算时钟调用开销和对结果进行统计分析.我想如果我只是测量我的C函数所需的时间,它将无法与Criterion返回的结果进行比较.在他关于Criterion的原始帖子中, Bryan O'Sullivan写道:"使用标准对C代码和命令行程序进行基准测试应该很容易." 问题是如何?Takayuki Muranushi 比较了DFT的C实现使用Haskell生成线程并调用可执行文件,但我担心这会增加很多额外的开销(创建新线程,运行应用程序,输出到stdio然后从中读取),这使得结果无法比拟.我也考虑使用FFI,但我再次担心额外的开销会使这种比较不公平.
如果没有办法使用Criterion可靠地对C进行基准测试,那么您会推荐哪种C基准测试方法?我在这里读过一些关于SO的问题,似乎有许多不同的函数可以测量系统时间,但是它们要么以毫秒为单位提供时间,要么有大量的调用开销.
我正在尝试优化一些代码,使用标准来尝试比较,例如,将INLINE
pragma 添加到函数的效果.但我发现重新编译/运行之间的结果并不一致.
我需要知道如何使结果在运行中保持一致,以便我可以比较它们,或者如何评估基准是否可靠,即(我猜)如何解释方差的细节,"成本时钟呼叫"等
这与我上面的主要问题是正交的,但是在我的特定情况下,有几件事可能导致不一致:
我正在尝试使用基准测试IO
操作,whnfIO
因为whnf
在此示例中使用的方法不起作用.
我的代码使用并发
我有很多标签和垃圾打开
这两个都来自相同的代码,以完全相同的方式编译.我直接在下面进行了第一次运行,做了一个更改并做了另一个基准测试,然后还原并再次运行第一个代码,编译:
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) 我有一个非递归函数来计算似乎表现良好的最长公共子序列(ghc 7.6.1
用-O2 -fllvm
标志编译),如果我Criterion
在同一模块中测量它.在另一方面,如果我转换功能为模块,只导出功能(如建议在这里),然后用标准重新测量,我得到〜2倍放缓(这会消失,如果我移动的标准测回模块其中定义了函数).我尝试用INLINE
pragma 标记函数,这对跨模块性能测量没有任何影响.
在我看来,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) 有一个从输出HTML的一个很好的例子标准在http://bos.github.com/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(称为生成器)放在一起,用< - 提取结果,然后将其传递给基准函数.我发现性能没有差别. …
我经常想比较同一函数的多个实现的运行时性能.对于个人投入,标准是一个很好的工具.
但是,在不同的输入大小上绘制代码性能的简单方法是什么,例如,查看算法的复杂性?
理想情况下,我向库传递一个类型的值Benchmarkable r => [(String, Int -> r)]
,即依赖于大小的基准列表,库将自动为每个值找到合理的输入范围,并从中创建一个漂亮的图.
benchmarking haskell graph time-complexity haskell-criterion
是否有Scala(或Java,我猜)相当于标准?我不仅仅是在讨论基准测试库:请查看HTML结果的标准.
我使用了库标准和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)