Java:main中奇怪的运行时行为
我在以下代码中体验到(对我而言)奇怪的运行时行为:Java:main中奇怪的运行时行为,java,runtime,behavior,Java,Runtime,Behavior,我在以下代码中体验到(对我而言)奇怪的运行时行为: 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(Stri
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.");
}
}
第一次呼叫比之后的呼叫慢约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)
那么,我的问题是:为什么会发生这种情况?即时(JIT)编译器正在动态分析代码并优化执行。一段代码执行的频率越高,其优化效果就越好
例如,有关更多信息,请参见此问题:您运行的其他应用程序可能会影响您在计算机上分配给JVM的内存量。运行java命令时,尝试将相同的最小和最大内存设置为JVM:
java -Xms512M -Xmx512M ...
在尝试运行时,我得到了相当一致的时间间隔:
String appending conversion took 1153ms.
String appending conversion took 1095ms.
String appending conversion took 1081ms.
我会将“strings”放在循环外,然后使用“s=Integer.toString(numberToConvert);”赋值。这可能会提高性能,因为它不会每次都创建新的字符串对象。@jlordo-是的,但按照您编写的方式,它会创建2个以上的字符串对象。按照我的建议,只有1个string对象用作引用。@jlordo代码最初指定用于比较“+和PrimitiveWrapper.toString()与string.valueOf()的运行时。这就是我遇到上述问题的地方。为了进一步研究这个特殊问题,我刚刚从源代码中删除了另外两个方法。无论如何,谢谢你的提示。:)@djangofan+1是我的错。我读得不够精确。您指的是
“”+int
部分,我刚才指的是move字符串s代码>在循环部分之外。@jlordo-ok。好吧,如果你真的仔细检查了代码,你也可以找到性能差异的其他原因。如果你仔细观察,我敢打赌你会找到罪魁祸首。第一次迭代中的缓存未命中和页面错误可能比第二次或后续迭代中的要多。@Dmitry Beransky:谢谢!在阅读您的链接后,我发现JIT编译器(我认为热点就是它的名字)是导致这种行为的原因。我找到了更多的信息。因此,我使用just对代码进行了测试,以发现所有调用消耗的时间大致相同。非常感谢。尝试过,但结果没有改变。
String appending conversion took 1153ms.
String appending conversion took 1095ms.
String appending conversion took 1081ms.