为什么Strings需要花费不同的时间来创建?

时间:2014-07-30 23:12:02

标签: java

有人可以向我解释这里发生了什么......

情景1

此:

// around 50ms
for (int i = 0; i < 3000000; i++) {
    String str = new String();
}

...比这更费时:

// around 25ms
for (int i = 0; i < 3000000; i++) {
    String str = new String("");
}

场景2

此:

String str = new String(); // around 3000ns

耗时

String str = new String(""); // around 5000ns

为什么在场景1中调用空String()构造函数会更耗时,但在场景2中却没有?我查看了String()和String(String original)的文档,但我看不到优化。这种优化(如果确实是优化)是在其他地方完成的吗?

更新

我如何计时:

long start = System.nanoTime();
//doing stuff here
long elapsedTime = System.nanoTime() - start;

我的系统:

Windows 7 x64,使用Java 7和Eclipse

3 个答案:

答案 0 :(得分:3)

如果不知道基准测试的结果会很难说,但是我会把我的钱放在System.nanoTime没有足够高的分辨率measure a single object instantiation上。我敢打赌String()String("")只需要少于nanoTime时钟的一个时钟来实例化,而你的结果就是你和#39;重新尝试测量小于它的分辨率的东西。

对于实例化,

This(三岁)问题指向~20 ns,而我之前提到的问题表明nanoTime的分辨率实际上是~10ns。我的猜测是你的实例化时间实际上介于10 ns和20 ns之间,看起来差别只是噪音。

编辑回应评论:

出了点问题。单个对象实例化可能需要3000 ns。我猜测你正在测量JVM预热时间或类似时间,也许""的存在导致JVM遇到一些没有""的情况下没有命中的代码路径。我不确定是什么导致了您的问题,但我不认为您所测量的是对象实例化时间。

答案 1 :(得分:1)

好的,我将此作为新答案提交,因为它与我的其他答案完全不同,并且评论中没有足够的空间。

您所看到的是System.nanoTime缺乏准确性,如下所述:Precision vs. accuracy of System.nanoTime()

在完成相同测试的多次迭代(适当的热身)后,我确定了以下内容(对于我的机器)

  • 新String()的耗用时间介于3.7和10.4ns之间,平均值约为4.1
  • 新字符串的经过时间(&#34;&#34;)介于6.0和14.8之间,平均值约为6.3
  • 对新String()和新String(&#34;&#34;)的单次调用都会返回0ns或307ns的时序,偶尔会有306ns。

这基本上证明帕特里克的答案是正确的。纳米时钟的精度并不足以测量单个呼叫。精确值只能确定为多个呼叫的平均值。在我的机器上,精度似乎是~300ns。

如果你能以某种方式测量一个单独的调用,我强烈怀疑它会显示新的String()与新的String(&#34;&#34;)相比具有相同的差异,无论你调用多少次它

答案 2 :(得分:0)

JVM可以进行运行时优化。在许多/大多数情况下,您只会注意到迭代次数较多的情况。在方案1中,可能一个人的优化程度不同于另一个。

尝试在禁用运行时优化的情况下运行,并看到您仍然会收到相互矛盾的结果。