有人能解释一下这是怎么回事吗..。
场景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原始)的doc,但是在那里看不到优化。这种优化(如果确实是优化的话)是在其他地方完成的吗?
更新:
我是怎么安排这个时间的:
long start = System.nanoTime();
//doing stuff here
long elapsedTime = System.nanoTime() - start;
我的系统:
Windows 7 x64,使用Java 7和Eclipse
发布于 2014-08-01 19:06:52
好吧,我把这个作为一个新的答案,因为它真的不同于我的另一个答案,而且在评论中没有足够的空间。
您所看到的是System.nanoTime中缺乏精确性,如下所述:Precision vs. accuracy of System.nanoTime()。
在运行了相同测试的多次迭代之后(通过适当的热身),我确定了以下(对于我的机器)
这基本上证明帕特里克的回答是正确的。纳米时钟的精度不足以测量单个呼叫。一个精确的值只能作为多个呼叫的平均值来确定。在我的机器上,精度似乎是300 be。
如果您能够以某种方式度量单个调用,我强烈怀疑它会显示与新字符串(“”)相比,无论调用多少次,新字符串(“”)都有相同的区别。
发布于 2014-07-30 23:33:14
如果不知道基准测试的结果,很难说,但我会把钱花在System.nanoTime
上,因为measure a single object instantiation的分辨率不够高。我敢打赌,String()
和String("")
都用不到nanoTime
时钟的一个滴答来实例化,而您的结果是一个假象,即您正在尝试测量小于其分辨率的东西。
This (三岁)问题在实例化中指向~20 ns,前面我所提到的问题表明,nanoTime
的分辨率实际上是10 ns。我猜你的实例化时间实际上是在10 ns到20 ns之间,而看起来不同的是噪音。
根据评论进行编辑:
有些地方不对劲。单个对象实例化不可能花费3000 ns。我猜您是在测量JVM的预热时间或类似的时间,也许""
的存在导致JVM到达了一些没有""
时它不会碰到的代码页。我不知道是什么引起了你的问题,但我不认为你测量的是对象实例化时间。
发布于 2014-07-30 23:22:48
JVM可以执行运行时优化。在许多/大多数情况下,您只会注意到迭代次数较多的地方。在场景1中,它很可能是以不同的方式进行优化的。
尝试在禁用运行时优化的情况下运行,然后看到您仍然得到冲突的结果。
https://stackoverflow.com/questions/25048479
复制相似问题