秒表基准测试是否可接受?

79

有人使用秒表基准测试吗?或者说性能工具总是应该被使用?是否有适用于Java的好的免费工具?你使用哪些工具呢?

为了澄清我的疑虑,秒表基准测试存在由于操作系统调度而产生的误差。在程序运行的某次中,操作系统可能会在你计时的函数执行期间调度另一个进程(或多个进程)。如果你尝试对线程化的Java应用程序进行计时,情况甚至会更加糟糕,因为JVM调度器会将一点不确定性添加到混合中。

在基准测试过程中,如何解决操作系统调度问题?


我建议使用Java微基准测试工具(JMH)来避免JVM的测量误差。在以下页面上了解有关JMH的更多信息:https://www.oracle.com/technical-resources/articles/java/architect-benchmarking.html 和 https://www.baeldung.com/java-microbenchmark-harness - StackOverflow
13个回答

52

秒表基准测试很好,只要你测量了足够的迭代次数才具有意义。通常,我需要一段单位为几秒钟的总经过时间。否则,你的结果很容易受到调度和其他操作系统中断对进程的影响而产生显著偏差。

为此,我使用了一组我很久以前构建的小型静态方法,这些方法是基于System.currentTimeMillis()

在分析工作中,我多年来一直使用jProfiler,发现它非常好用。最近,我看过YourKit,从网站上看似乎很棒,但我个人还没有使用过。

回答有关调度中断的问题,我发现重复运行直到观察到一致性实践中可用于清除进程调度中异常结果。我也发现线程调度对于5到30秒的运行没有实际影响。最后,在你越过几秒钟阈值之后,我发现调度在我的经验中对结果的影响微不足道 - 我发现5秒的运行平均与5分钟的运行时间/迭代相同。

你也可以考虑预运行测试代码约10,000次以“热身”JIT,这取决于你期望测试代码在实际生产中运行的次数。


7
只要你测量的时间间隔足够大,它就是完全有效的。我会执行20-30次你打算测试的内容,这样总经过时间超过1秒钟。我注意到基于System.currentTimeMillis()的时间计算 tend to be either 0ms or ~30ms; 我认为你无法获得更精确的结果。如果你真的需要测量小时间间隔,你可以尝试使用System.nanoTime():
文档:http://java.sun.com/javase/6/docs/api/java/lang/System.html#nanoTime() 关于测量小时间间隔的SO问题,因为System.nanoTime()也有一些问题:How can I measure time with microsecond precision in Java?

6

秒表实际上是最好的基准!

真正的端到端用户响应时间才是真正重要的时间。

通常情况下,使用现有工具无法获得此时间,例如大多数测试工具不包括浏览器呈现页面所需的时间,因此对于具有糟糕编写CSS的超复杂页面,测试工具将显示低于一秒的响应时间,但实际用户响应时间可能超过5秒。

这些工具非常适用于自动化测试和问题确定,但不要忘记您真正想要测量的内容。


5

性能分析器可以提供更加详细的信息,有助于诊断和解决性能问题。

就实际测量而言,秒表时间是用户所注意到的,因此如果您想要验证事物是否在可接受的限制范围内,秒表时间是可以的。

然而,当您真正想要解决问题时,性能分析器可以非常有帮助。


4
你需要测试足够多的迭代次数,因为不同的计时方法会得到不同的答案。如果只执行一次操作,则取多次迭代的平均值可能会误导。如果想要知道JVM预热后所需时间,则可以运行许多(例如10,000)未包含在计时中的迭代。
我还建议您使用System.nanoTime(),因为它更加精确。如果你的测试时间大约在10微秒或更短,你不应该过于频繁地调用它,否则可能会改变你的结果。(例如,如果我正在测试5秒钟,并且想知道何时结束,我只有在每1000次迭代时才获取nanoTime,如果我知道一个迭代非常快)

2
当进行基准测试时,如何处理操作系统调度问题?
在代表将要使用的计算机的系统上进行足够长时间的基准测试。如果您的操作系统减慢了应用程序的运行速度,则这应该是结果的一部分。
没有必要说:“如果我没有操作系统,我的程序会更快。”
如果您正在使用Linux,则可以使用工具,例如numactl、chrt和taskset来控制CPU的使用和调度。

2

性能分析器可能会干扰计时,因此我建议使用秒表计时来识别整体性能问题,然后再使用性能分析器找出时间花费在哪里。如有需要,请重复该过程。


1
今天我运行了一个程序,它搜索并收集了一堆dBase文件中的信息,运行时间略长,大约一个小时。我查看了代码,猜测了瓶颈所在,并对算法进行了微小的改进,然后重新运行程序,这次只用了2.5分钟
我不需要任何高级的分析工具或基准测试套件来告诉我新版本是一个重大的改进。如果我需要进一步优化运行时间,我可能会进行更复杂的分析,但这并不是必要的。我发现这种“秒表基准测试”在许多情况下都是可接受的解决方案,在这些情况下使用更高级的工具实际上会更耗时。

2
我不介意因为合理的原因而被踩,但是请至少有点礼貌,在你踩我的回答时解释一下哪里出了问题或者哪里不够有帮助。 - Robert Gamble

1

毕竟,它可能是第二受欢迎的基准测试形式,仅次于“无表观测基准测试”——我们说“这个活动似乎很慢,那个似乎很快。”

通常最重要的优化是干扰用户体验的任何因素——这往往取决于您执行操作的频率以及同时进行的其他操作。其他形式的基准测试通常只是帮助聚焦于这些问题。


1

我认为一个关键问题是操作的复杂性和时间长度。

有时候,我甚至使用物理秒表测量来判断某个操作需要几分钟、几小时、几天,甚至几周才能完成(我正在处理的应用程序中,运行时间长达数天并不罕见,尽管秒和分钟是最常见的时间跨度)。

然而,通过调用计算机上任何类型的时钟系统(如链接文章中提到的Java millis调用)所提供的自动化功能,显然比手动查看运行时间更优越。

分析器很好用,但当它们无法正常工作时,我就会遇到问题。我们的应用程序通常涉及动态代码生成、DLL的动态加载以及在应用程序的两种内置即时编译脚本语言中执行的工作。它们往往只能假设单一源语言和其他对于复杂软件不切实际的期望。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接