2017-05-12 51 views
0

我感兴趣的是比较两种不同功能的速度,对两种功能使用相同的输入数据(BMP)。我们应该测量函数的平均执行时间还是最小执行时间?


当我们衡量一个函数的执行时间(使用相同的总输入),我们没有得到相同的结果(时间),即使我们应该因为该节目在多任务环境中运行。即使我们将程序作为“高优先级”运行,来自其他程序的干扰也会减慢我们的程序(为了简化考虑单个核心计算机)。

因此,大多数人会多次计时,并取平均值。我的问题是为什么我们不记录最小的执行时间而不是平均值?最小执行时间应该比平均执行时间更接近实际情况。

+0

它只反映真实的执行时间,如果没有不同的执行路径可以采取。一个执行路径可能比另一个执行路径更长/更慢。例如,如果某些条件不符合,最短(及时)可能仅仅是一个早期回报。这并不能反映典型的执行时间,这是大多数人想知道的。举个例子,我的BigInteger.divide()。如果传入的除数为零,则执行时间很短。但如果情况并非如此,它可能会很长。 –

+1

执行时间较长的存在证明该函数可能花费比测量的最小时间更长的时间。大多数人对任意时间任意负载下的性能感兴趣。 –

+0

对不起。我还没有很好地定义这个问题。我添加了这个:“测量函数的执行时间(总是使用相同的输入)” - 因此,现在没有不同的执行路径。再次抱歉。 – Ampere

回答

1

您应该始终瞄准最短时间。
因为如果你这样做,你确信你只是计时自己的代码,没有别的。

为目的的最短时间
如果你的代码只有一个执行路径,那么你应该始终以最短时间(出很多很多重复的)作为所采取的实际时间。
通过这种方式,您可以在一个或两个CPU周期内准确计时。 为了清楚起见,您运行数百万次运行的代码段,并以该运行的最低采样作为时间。
然后,您将这些数百万次运行放在循环运行10倍或100倍的循环中,并再次采用最低的时间。像这样:

Lowest = MaxInt; 
loop 100x 
    loop million times 
    Clock.Start; 
    DoTest; 
    Timing = Clock.Time; 
    if (timing < Lowest) {Lowest = timing} 

其他循环重置有时帮助的上下文。这很重要,如果JIT编译器迟到。外循环给它一个重置的改变。

你也可以在外循环中进行计时,如果代码片段特别快,则可以除以一百万。在这种情况下,您将运行一个额外的空时序循环,并从繁忙循环中花费的时间中减去空循环占用的时间。
虽然为了防止代码优化消除空循环,你必须变得聪明:-)。

如果您的代码有多个可能的路径,那么您不能真正计算其执行时间。只使用固定输入运行一个简单的循环,因为这只会给你一段代码路径的部分时间。这可能不代表真实世界的表现。

让您的跑步确定性
总是试图修复代码所以代码只能取一个路径。
或尝试设置测试,以便连续采用所有可能的路径,然后计算所有事情所需的最短时间,并除以测试的代码路径的数量。

一切和厨房水槽剖析
如果这是不可能的,你必须取平均值,但要注意,在这种情况下,你没有真正定时只是你的代码了,你还考虑系统开销,HDD中断和后台进程。