如何进行良好的性能对比测试?

时间:2013-03-08 12:52:12

标签: java performance jvm

要编写一个好的比较测试测试,你必须运行几千(数百万)次。它将平衡(在大多数情况下)其他程序的影响力。

但是如果JVM可以影响结果。例如:

第一个解决方案是:

    final StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(getStrOne());
    stringBuilder.append(getStrTwo());
    final String result1 = stringBuilder.toString();

第二是:

    final String result2 = getStrOne() + getStrTwo();

我不知道哪一个更好,因为JVM可以影响结果。如何知道哪一个更好?

更新:我并不是说 附加了验证测试。我问的是这样一个难以测试的情况

2 个答案:

答案 0 :(得分:2)

我最近执行了一些基准测试,这些测试依赖于此处发现的优秀IBM文章:http://www.ibm.com/developerworks/java/library/j-benchmark1/index.html

本文介绍了许多可能影响结果准确性的缺陷,例如:

  • 运行时优化/重新编译代码。
  • 消除死代码(即未使用的结果可能导致您的测试代码被删除)
  • 垃圾收集
  • 缓存
  • ...

最后,文章链接到框架可以downloaded的网站。该框架很好地完成了一个测试方法,寻找重新编译的证据并等待执行时间来解决。

答案 1 :(得分:0)

如果是2个字符串,性能差异可以忽略不计,但请尝试以下方法:

String s = "";
for( int i = 0; i < 10000; i++ ) {
  s += i;
}

VS

StringBuilder b = new StringBuilder();
for( int i = 0; i < 10000; i++ ) {
  b.append(i);
}

您会发现第二个循环更快。为什么?因为字符串连接将在每次​​迭代中创建一个新的String对象,这会浪费CPU周期和内存。

我会引用你的话:

  

要编写一个好的比较测试测试,你必须测试几千(数百万)次。它将平衡(在大多数情况下)其他程序&#39;影响。

这同样适用于单个VM中的测试:多次测试您的代码,使用更大的数据,更大的循环等。由于定时精度错误和其他影响(例如垃圾收集),只比较小部分是没有意义的在两者之间奔跑)。