Java 我们应该测量函数的平均执行时间还是最小执行时间?

Java 我们应该测量函数的平均执行时间还是最小执行时间?,java,c++,profiling,execution,timing,Java,C++,Profiling,Execution,Timing,我感兴趣的是比较两个不同函数的速度,对两个函数使用相同的输入数据(BMP) 当我们测量函数的执行时间(总是使用相同的输入)时,即使我们应该得到相同的结果(时间),我们也不会得到相同的结果(时间),因为程序运行在多任务环境中。即使我们的程序运行为“高优先级”,来自其他程序的干扰也会减慢我们的程序(以简化考虑单核计算机)。 因此,大多数人会对函数进行多次计时并得出平均值。我的问题是为什么不记录最小的执行时间而不是平均执行时间?最小执行时间应该比平均执行时间更接近实际情况。您应该始终以最短时间为目标

我感兴趣的是比较两个不同函数的速度,对两个函数使用相同的输入数据(BMP)


当我们测量函数的执行时间(总是使用相同的输入)时,即使我们应该得到相同的结果(时间),我们也不会得到相同的结果(时间),因为程序运行在多任务环境中。即使我们的程序运行为“高优先级”,来自其他程序的干扰也会减慢我们的程序(以简化考虑单核计算机)。
因此,大多数人会对函数进行多次计时并得出平均值。我的问题是为什么不记录最小的执行时间而不是平均执行时间?最小执行时间应该比平均执行时间更接近实际情况。

您应该始终以最短时间为目标。
因为如果你这样做了,你肯定你只是在给自己的代码计时,而不是别的

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

Lowest = MaxInt;
loop 100x 
  loop million times
     Clock.Start;
     DoTest;
     Timing = Clock.Time;
     if (timing < Lowest) {Lowest = timing}
lower=MaxInt;
回路100x
循环百万次
时钟。开始;
溺爱;
计时=时钟。时间;
如果(定时<最低){最低=定时}
另一个循环重置上下文,这有时会有所帮助。这很重要,例如,如果JIT编译器延迟启动。外部循环使其更改为重置

如果代码段特别快,还可以在外循环中计算计时,然后除以一百万。在这种情况下,您将运行一个额外的空计时循环,并从繁忙循环中所花费的时间中减去空循环所花费的时间。
但是,您必须聪明地防止代码优化消除空循环:-)

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

让您的跑步具有确定性
始终尝试修复代码,以便代码只能使用一条路径。
或者尝试设置测试,以便连续获取所有可能的路径,然后计算所有操作所需的最短时间,并除以测试的代码路径数

所有东西和厨房水槽的轮廓

如果这是不可能的,您将不得不采用平均值,但请注意,在这种情况下,您不再只是对代码进行计时,还需要考虑系统开销、HDD中断和后台进程

只有在没有不同的执行路径时,它才能反映实际执行时间。一条执行路径可能比另一条执行路径长/慢得多。例如,如果不满足某些条件,最短的(时间)可能就是提前返回。这并不反映典型的执行时间,这也是大多数人想要知道的。以我的biginger.divide()为例。如果传入的除数为零,则执行时间非常短。但如果不是这样的话,它也可能非常长。更长的执行时间的存在证明了函数可能需要比最小测量值更长的时间。大多数人都对在任意时间任意加载下的性能感兴趣。对不起。我没有很好地定义这个问题。我添加了这样一句话:“测量函数的执行时间(使用始终相同的输入)”——因此,现在没有不同的执行路径。再次抱歉。这仍然没有给你多少信息,除非你用许多不同的输入测试它。