gat*_*ado 15 performance haskell haskell-criterion
我正在尝试使用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 (-) &&& alternatingOp (+)) where
alternatingOp op x = V.generate (V.length x `div` 2) (\i ->
((x V.! (2 * i)) `op` (x V.! (2 * i + 1))) * invSqrt2)
haarDWT :: V.Vector Float -> V.Vector Float
haarDWT xl@(V.length -> 1) = xl
haarDWT (haarStep -> (d, s)) = haarDWT s V.++ d
main = do
gen <- getStdGen
inData <- return $ getRandList gen 2097152
outData <- return $ haarDWT (V.fromList inData)
defaultMain [
bench "get input" $ nf id inData,
bench "transform" $ nf V.toList outData
]
writeFile "input.dat" (unlines $ map show inData)
writeFile "output.dat" (unlines $ map show $ V.toList outData)
Run Code Online (Sandbox Code Playgroud)
最后,当我尝试调用它时,我收到了一个错误-s 1; 也许这只是一个标准错误.
Main: ./Data/Vector/Generic.hs:237 ((!)): index out of bounds (1,1)
Run Code Online (Sandbox Code Playgroud)
提前致谢!
发布的基准是非常慢的......或者是它
你确定它是错误的吗?你正在接触(好吧,"nf"电话正在触摸)200万盒装元素 - 这是400万个指针.如果你愿意,你可以称之为错误,但问题就在于你认为自己衡量的是与你真正测量的相比.
在基准之间共享数据
数据共享可以通过部分应用来完成.在我的基准测试中,我通常都有
let var = somethingCommon in
defaultMain [ bench "one" (nf (func1 somethingCommon) input1)
, bench "two" (nf (func2 somethingCommon) input2)]
Run Code Online (Sandbox Code Playgroud)
在懒惰评估的情况下避免重复使用
标准通过分离您的功能和输入来避免共享.你有签名,如:
funcToBenchmark :: (NFData b) => a -> b
inputForFunc :: a
Run Code Online (Sandbox Code Playgroud)
在Haskell中,每次应用funcToBenchmark inputForFunc它都会创建一个需要评估的thunk.除非您使用与先前计算相同的变量名称,否则不会共享.没有自动记忆 - 这似乎是一个常见的误解.
注意不共享内容的细微差别.我们没有分享最终结果,但输入是共享的.如果输入的生成是你想要的基准(即getRandList,在这种情况下)然后基准那个而不仅仅是身份+ nf函数:
main = do
gen <- getStdGen
let inData = getRandList gen size
inVec = V.fromList inData
size = 2097152
defaultMain
[ bench "get input for real" $ nf (getRandList gen) size
, bench "get input for real and run harrDWT and listify a vector" $ nf (V.toList . haarDWT . V.fromList . getRandList gen) size
, bench "screw generation, how fast is haarDWT" $ whnf haarDWT inVec] -- for unboxed vectors whnf is sufficient
Run Code Online (Sandbox Code Playgroud)
解释数据
第三个基准是相当有启发性的.让我们看看打印出来的标准:
benchmarking screw generation, how fast is haarDWT
collecting 100 samples, 1 iterations each, in estimated 137.3525 s
bootstrapping with 100000 resamples
mean: 134.7204 ms, lb 134.5117 ms, ub 135.0135 ms, ci 0.950
Run Code Online (Sandbox Code Playgroud)
基于单次运行,Criterion认为执行100个样本需要137秒.大约十秒钟后,它完成了 - 发生了什么?好吧,第一次运行强制所有输入(inVec),这是昂贵的.随后的运行发现了一个值而不是一个thunk,因此我们真正地进行了基准测试,haarDWT而不是StdGenRNG(已知它非常缓慢).
| 归档时间: |
|
| 查看次数: |
2353 次 |
| 最近记录: |