有人可以向我解释这里发生了什么......
情景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
答案 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()。
在完成相同测试的多次迭代(适当的热身)后,我确定了以下内容(对于我的机器)
这基本上证明帕特里克的答案是正确的。纳米时钟的精度并不足以测量单个呼叫。精确值只能确定为多个呼叫的平均值。在我的机器上,精度似乎是~300ns。
如果你能以某种方式测量一个单独的调用,我强烈怀疑它会显示新的String()与新的String(&#34;&#34;)相比具有相同的差异,无论你调用多少次它
答案 2 :(得分:0)
JVM可以进行运行时优化。在许多/大多数情况下,您只会注意到迭代次数较多的情况。在方案1中,可能一个人的优化程度不同于另一个。
尝试在禁用运行时优化的情况下运行,并看到您仍然会收到相互矛盾的结果。