全球/本地环境影响Haskell的标准基准结果 [英] Global / local environment affects Haskell's Criterion benchmarks results

查看:129
本文介绍了全球/本地环境影响Haskell的标准基准结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在对我们公司的一些Haskell代码进行基准测试,我们刚刚遇到了一个非常奇怪的例子。这是一个代码,它将基准测试同样的东西2次。前者使用一次为所有测试创建的 Criterion.env ,后者为每个测试创建env。这是唯一的区别,但是为每个替补创建env的运行速度提高了5倍。

有谁知道可能导致什么?最小的例子:

  module Main其中

导入前奏
导入Control.Monad
将符合条件的Data.Vector.Storable.Mutable导入为
将符合条件的Data.Vector.Storable导入为Vector
导入Data.Vector.Storable(Vector)
import Criterion.Main


testf :: Int - > Vector Int - > IO(Vector Int)
testf!i!v = do
mv< - Vector.unsafeThaw v
放手j = do
x< - 如果j == 0则(j< i - 1)$ go(j + 1)
时,返回0 else vector.unsafeRead mv(j - 1)
Vector.unsafeWrite mv j去0
Vector.unsafeFreeze mv

mkVec :: Int - > IO(Vector Int)
mkVec!i = Vector.unsafeFreeze =<< Vector.new(i + 1)
$ b $ main :: IO()
main = do
defaultMain
[bgroupenv per run
$(\(i :: Int) - > env(mkVec(10 ^ i))
$ \v - > bench(10e++ show i)
$ nfIO testf(10 ^ i)v))< $> [7..8]

,bgroupenv per run
$(\(i :: Int) - > bench(10e++ show i)
$ perRunEnv(mkVec(10 ^ i))
$(testf(10 ^ i)))< $> [7..8]
]

结果:

 基准测试env per all runs / 10e7 
time 17.34 ms(17.20 ms .. 17.41 ms)
0.999R²(0.998R².. 1.000R²)
平均17.43毫秒(17.34毫秒.. 17.67毫秒)
标准开发321.5微秒(142.1微秒.. 591.3微秒)

基准测试env per all runs / 10e8
时间173.5 ms(173.2 ms .. 173.8 ms)
1.000R²(1.000R².. 1.000R²)
表示173.8 ms(173.6 ms .. 174.0 ms)
std dev 279.5 μs(194.9μs。355.6μs)异常值引入的
方差:12%(适度膨胀)

基准环境每次运行/ 10e7
时间4.289 ms(1.807 ms。 5.771毫秒)
0.924R²(0.696R².. 1.000R²)
表示8.903 ms(5.752 ms .. 14.20 ms)
std dev 5.029 ms (249.0μs.. 6.244 ms)异常值导致的
差异:79%(严重膨胀)

每次运行的基准环境/ 10e8
时间53.76 ms(30.23 ms .. 98.51 ms)
0.940R²(0.920R².. 1.000R²)
表示102.9 ms(68.67 ms。127.1 ms)
std dev 36.55 ms(0.0 s .. 41.99 ms)$ b由异常值引入的$ b变异:73%(严重膨胀)


解决方案

<与你大概的同事的问题一样,我不能再现这个问题。注意我使用的是GHC 8.2.2和条件1.3.0.0

 基准测试env per all runs / 10e7 
time 18.94 ms(18.71 ms .. 19.22 ms)
0.999R²(0.998R².. 1.000R²)
的平均值为19.59 ms(19.39 ms。19.99 ms)
std dev 618.3μs(379.7μs。 。952.8μs)

基准测试env per all runs / 10e8
time 192.0 ms(189.5 ms .. 194.9 ms)
1.000R²(0.999R².. 1.000R²)
平均值191.8毫秒(190.3毫秒.. 193.1毫秒)
标准差1.778毫秒(1.088毫秒.. 2.457毫秒)异常值引起的
差异:14%(适度膨胀)

基准env每次运行/ 10e7
时间18.97毫秒(18.38毫秒.. 19.62毫秒)
0.999R²(0.996R².. 1.000R²)
平均18.98毫秒(18.83毫秒.. 19.35 ms)
std dev 298.8μs(25.39μs。391.3μs )
由异常值引起的变化:14%(适度膨胀)

每次运行的基准测试env / 10e8
时间194.0 ms(182.0 ms .. 211.6 ms)
0.999R²(0.997R².. 1.000R²)
表示192.0 ms(189.0 ms .. 193.9 ms)
std dev 2.850 ms(0.0 s .. 3.261 ms)
由离群值引入的变化: 19%(适度膨胀)

./p 18.32s用户1.16s系统99%cpu 19.531总额
%ghc-pkg列表标准
...
标准-1.3.0.0

我注意到我的标准版本在bug @jberryman指出的bug被修复后被上传,所以也许这是区别。


We're benchmarking some Haskell code in our company and we've just hit a very strange case. Here is a code, which benchmarks the same thing 2 times. The former one uses an Criterion.env which is created for all the tests once, the later creates env for every test. This is the only difference, however the one which creates env for each bench, runs 5 times faster.

Does anyone know what can cause it? Minimal example:

module Main where

import Prelude
import Control.Monad
import qualified Data.Vector.Storable.Mutable as Vector
import qualified Data.Vector.Storable         as Vector
import           Data.Vector.Storable         (Vector)
import           Criterion.Main


testf :: Int -> Vector Int -> IO (Vector Int)
testf !i !v = do
    mv <- Vector.unsafeThaw v
    let go j = do
          x <- if j == 0 then return 0 else Vector.unsafeRead mv (j - 1)
          Vector.unsafeWrite mv j (x+1)
          when (j < i - 1) $ go (j + 1)
    go 0
    Vector.unsafeFreeze mv

mkVec :: Int -> IO (Vector Int)
mkVec !i = Vector.unsafeFreeze =<< Vector.new (i + 1)

main :: IO ()
main = do
    defaultMain
        [ bgroup "env per all runs"
            $ (\(i :: Int) -> env (mkVec (10 ^ i))
            $ \v -> bench ("10e" ++ show i)
            $ nfIO (testf (10 ^ i) v))  <$> [7..8]

        , bgroup "env per every run"
            $ (\(i :: Int) -> bench ("10e" ++ show i)
            $ perRunEnv (mkVec (10 ^ i))
            $ (testf (10 ^ i)))  <$> [7..8]
        ]

And results:

benchmarking env per all runs/10e7
time                 17.34 ms   (17.20 ms .. 17.41 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 17.43 ms   (17.34 ms .. 17.67 ms)
std dev              321.5 μs   (142.1 μs .. 591.3 μs)

benchmarking env per all runs/10e8
time                 173.5 ms   (173.2 ms .. 173.8 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 173.8 ms   (173.6 ms .. 174.0 ms)
std dev              279.5 μs   (194.9 μs .. 355.6 μs)
variance introduced by outliers: 12% (moderately inflated)

benchmarking env per every run/10e7
time                 4.289 ms   (1.807 ms .. 5.771 ms)
                     0.924 R²   (0.696 R² .. 1.000 R²)
mean                 8.903 ms   (5.752 ms .. 14.20 ms)
std dev              5.029 ms   (249.0 μs .. 6.244 ms)
variance introduced by outliers: 79% (severely inflated)

benchmarking env per every run/10e8
time                 53.76 ms   (30.23 ms .. 98.51 ms)
                     0.940 R²   (0.920 R² .. 1.000 R²)
mean                 102.9 ms   (68.67 ms .. 127.1 ms)
std dev              36.55 ms   (0.0 s .. 41.99 ms)
variance introduced by outliers: 73% (severely inflated)

解决方案

As with your presumably-coworker's question, I can not reproduce this issue. Note I am using GHC 8.2.2 and criterion 1.3.0.0

benchmarking env per all runs/10e7
time                 18.94 ms   (18.71 ms .. 19.22 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 19.59 ms   (19.39 ms .. 19.99 ms)
std dev              618.3 μs   (379.7 μs .. 952.8 μs)

benchmarking env per all runs/10e8
time                 192.0 ms   (189.5 ms .. 194.9 ms)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 191.8 ms   (190.3 ms .. 193.1 ms)
std dev              1.778 ms   (1.088 ms .. 2.457 ms)
variance introduced by outliers: 14% (moderately inflated)

benchmarking env per every run/10e7
time                 18.97 ms   (18.38 ms .. 19.62 ms)
                     0.999 R²   (0.996 R² .. 1.000 R²)
mean                 18.98 ms   (18.83 ms .. 19.35 ms)
std dev              298.8 μs   (25.39 μs .. 391.3 μs)
variance introduced by outliers: 14% (moderately inflated)

benchmarking env per every run/10e8
time                 194.0 ms   (182.0 ms .. 211.6 ms)
                     0.999 R²   (0.997 R² .. 1.000 R²)
mean                 192.0 ms   (189.0 ms .. 193.9 ms)
std dev              2.850 ms   (0.0 s .. 3.261 ms)
variance introduced by outliers: 19% (moderately inflated)

./p  18.32s user 1.16s system 99% cpu 19.531 total
% ghc-pkg list criterion
...
    criterion-1.3.0.0

I notice my version of criterion was uploaded after the bug @jberryman pointed to was fixed, so perhaps this is the difference.

这篇关于全球/本地环境影响Haskell的标准基准结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆