【发布时间】:2012-11-28 23:22:12
【问题描述】:
我在以下代码中遇到了(对我而言)奇怪的运行时行为:
public class Main{
private final static long ROUNDS = 1000000;
private final static double INITIAL_NUMBER = 0.45781929d;
private final static double DIFFERENCE = 0.1250120303d;
public static void main(String[] args){
doSomething();
doSomething();
doSomething();
}
private static void doSomething(){
long begin, end;
double numberToConvert, difference;
numberToConvert = INITIAL_NUMBER;
difference = DIFFERENCE;
begin = System.currentTimeMillis();
for(long i=0; i<ROUNDS; i++){
String s = "" + numberToConvert;
if(i % 2 == 0){
numberToConvert += difference;
}
else{
numberToConvert -= difference;
}
}
end = System.currentTimeMillis();
System.out.println("String appending conversion took " + (end - begin) + "ms.");
}
}
我希望程序每次都能打印出类似的运行时。但是,我得到的输出总是这样:
String appending conversion took 473ms.
String appending conversion took 362ms.
String appending conversion took 341ms.
第一次调用比之后的调用慢约 30%。大多数时候,第二次调用也比第三次调用稍慢。
java/javac 版本:
javac 1.7.0_09 java version "1.7.0_09" OpenJDK Runtime Environment (IcedTea7 2.3.3) (7u9-2.3.3-0ubuntu1~12.04.1) OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)
那么,我的问题是:为什么会发生这种情况?
【问题讨论】:
-
我会将“String s”放在循环之外,然后使用“s = Integer.toString(numberToConvert);”分配值.这可能会提高性能,因为它不会每次都创建新的 String 对象。
-
@jlordo - 是的,但是您编写它的方式,它创建了 2+ 个字符串对象。按照我的建议,只有 1 个字符串对象用作参考。
-
@jlordo 该代码最初指定用于比较 "" +
和 PrimitiveWrapper.toString( ) 和 String.valueOf( ) 的运行时。那就是我遇到上述问题的地方。我只是从源代码中删除了其他两种方法,以进一步研究这个特殊问题。无论如何感谢您的提示。 :) -
@djangofan +1 我的错。我读得不够准确。您指的是
"" + int部分,我只是指循环部分之外的moveString s;。 -
@jlordo - 好的。好吧,如果您真的仔细检查了代码,您也可以找到导致性能差异的其他原因。我敢打赌,如果你足够努力,你会找出罪魁祸首。