代码之家  ›  专栏  ›  技术社区  ›  Paul Biggar

如何衡量由许多子基准组成的基准的可变性?

  •  4
  • Paul Biggar  · 技术社区  · 14 年前

    我有一个基准, ,它由许多子基准组成 1 .. . 这是一个相当嘈杂的测试,结果是相当多变的。为了准确地进行基准测试,我必须减少这种“可变性”,这要求我首先 可变性。

    我自己对这个问题的尝试是:

    sum = 0
    foreach i in 1..n
       calculate mean across the 60 runs of x_i
       foreach j in 1..60
           sum += abs(mean[i] - x_i[j])
    variability = sum / 60
    
    5 回复  |  直到 14 年前
        1
  •  2
  •   Community CDub    8 年前

    最佳创意: ask at the statistics Stack Exchange once it hits public beta (一周后)。

    典型的 用户体验,但通过改进 用户体验。尝试第95个百分位的标准差,并努力减少。或者,如果 你想减少什么,把标准差都画在一起。如果它们是近似正态分布,我不知道为什么你不能取平均值。

        2
  •  1
  •   sarnold    14 年前

    我觉得你误解了 standard deviation --如果您运行测试50次,并且有50个不同的运行时 标准差 将是一个单一的数字,描述如何紧或松这50个数字分布在你的平均水平。与您的 平均的 运行时,标准差将帮助您查看结果中有多大的差异。

    考虑以下运行时:

    12 15 16 18 19 21 12 14

    15.875 . 本组样本标准差为3.27。有一个很好的解释3.27实际上是什么 方法 (在正态分布的人群中,大约68%的样本将落在平均值的一个标准差之内:例如,介于 15.875-3.27 15.875+3.27 )但我认为你只是在寻找一种方法来量化结果有多“紧”或“分散”在你的平均值附近。

    现在考虑一组不同的运行时(例如,在使用编译所有测试之后) -O2

    14 16 14 17 19 21 12 14

    这些运行时间的平均值也是 15.875 . 这组样品的标准偏差为3.0(所以,大约68%的样本会落在 15.875-3.0 15.875+3.0

    你有一个单一的数字,它总结了一组数字在平均值附近是紧凑的还是松散的。

    注意事项

    标准差建立在 normal distribution --但是您的应用程序可能不是正态分布的,所以请注意,标准差充其量只是一个粗略的指南。在地图中绘制您的跑步时间 histogram

    另外,我使用的是样本标准差,因为这只是基准运行总体空间中的一个样本。我不是一个专业的统计学家,所以即使是这个基本假设也可能是错误的。无论是总体标准差还是样本标准差,只要您坚持使用样本或总体,就可以在应用程序中获得足够好的结果。别把两者混为一谈。

    分散,也许你的过程不太可重复。解释 3%

    最后一点:是的,你可以手工计算标准差,但是在前十个左右的时间之后,它会很乏味。最好使用电子表格或wolfram alpha或你方便的高中计算器。

        3
  •  1
  •   denis    14 年前

    Variance : 总组的方差等于各子群方差的均值加上各子群均值的方差

    #!/usr/bin/env python
    import sys
    import numpy as np
    
    N = 10
    exec "\n".join( sys.argv[1:] )  # this.py N= ...
    np.set_printoptions( 1, threshold=100, suppress=True )  # .1f
    np.random.seed(1)
    
    data = np.random.exponential( size=( N, 60 )) ** 5  # N rows, 60 cols
    row_avs = np.mean( data, axis=-1 )  # av of each row
    row_devs = np.std( data, axis=-1 )  # spread, stddev, of each row about its av
    print "row averages:", row_avs
    print "row spreads:", row_devs
    print "average row spread: %.3g" % np.mean( row_devs )
    
    # http://en.wikipedia.org/wiki/Variance:
    # variance of the total group
    # = mean of the variances of the subgroups  +  variance of the means of the subgroups
    avvar = np.mean( row_devs ** 2 )
    varavs = np.var( row_avs )
    print "sqrt total variance: %.3g = sqrt( av var %.3g + var avs %.3g )" % (
        np.sqrt( avvar + varavs ), avvar, varavs)
    
    var_all = np.var( data )  # std^2 all N x 60 about the av of the lot
    print "sqrt variance all: %.3g" % np.sqrt( var_all )
    

    row averages: [  49.6  151.4   58.1   35.7   59.7   48.   115.6   69.4  148.1   25. ]
    row devs: [ 244.7  932.1  251.5   76.9  201.1  280.   513.7  295.9  798.9  159.3]
    average row dev: 375
    sqrt total variance: 464 = sqrt( av var 2.13e+05 + var avs 1.88e+03 )
    sqrt variance all: 464
    


    要查看组差异是如何增加的,请运行wikipediavariance中的示例。
    60 men of heights 180 +- 10, exactly 30: 170 and 30: 190  
    60 women of heights 160 +- 7, 30: 153 and 30: 167.  
    

    平均标准偏差为(10+7)/2=8.5。 但是一起,高地

    -------|||----------|||-|||-----------------|||---
           153          167 170                 190
    

    像170+-13.2一样扩散,远大于170+-8.5。
    为什么?因为我们不仅有男性+10和女性+7, 但也有从160/180左右的价差共同均值170。
    练习:用两种方法计算价差13.2,

        4
  •  0
  •   Donal Fellows    14 年前

    这是一个棘手的问题,因为基准可以具有不同的自然长度。因此,您需要做的第一件事是将每个子基准数字转换为比例不变值(例如,相对于某个可靠的基准线的加速因子),这样您至少有一个 机会 比较不同的基准。

    然后你需要选择一种组合数字的方法。有点普通。然而,有许多类型的平均值。我们可以拒绝使用模式和中位数在这里;他们扔掉了太多的相关信息。但是不同类型的平均值是有用的,因为它们赋予异常值权重的方式不同。我过去知道(但已经忘记)是几何平均数还是调和平均数在实践中最有用(算术平均数在这里不太好)。几何平均数基本上是对数域的算术平均数,调和平均数同样是倒数域的算术平均数(电子表格使这变得微不足道。)

    请注意,这是一个缓慢的业务,很难得到正确的,它通常没有信息引导。基准只对基准中的内容进行性能测试,而人们通常不会这样使用代码。最好的办法可能是严格考虑时间限制您的基准测试工作,而不是把重点放在用户是否认为软件是正确的 感知 是否足够快,或者是否在部署中实际达到了所需的事务速率(有许多非编程方式会把事情搞砸)。

    祝你好运!

        5
  •  -1
  •   ruslik    14 年前

    你试图解决错误的问题。最好尽量减少。差异可能是由于缓存造成的。

    停止阅读。

    如果您有许多条件跳转,它会在具有不同输入的调用之间引入明显的差异(这可以通过为第i次迭代提供完全相同的输入来解决,然后比较这些迭代之间的测量时间)。

    您可以在这里找到一些有用的提示: http://www.agner.org/optimize/optimizing_cpp.pdf