2

我在以下代码中遇到了(对我而言)奇怪的运行时行为:

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)

所以,我的问题是:为什么会发生这种情况?

4

2 回答 2

6

即时 (JIT) 编译器正在动态分析您的代码并优化执行。一段代码执行得越频繁,它的优化就越好。

例如,请参阅此问题以获取更多信息:(如何)Java JIT 编译器优化我的代码?

于 2012-11-28T23:24:33.423 回答
0

您正在运行的其他应用程序可能会影响您分配给机器上 JVM 的内存量。尝试在运行 java 命令时为 JVM 设置相同的最小和最大内存:

java -Xms512M -Xmx512M ...

尝试运行它时,我得到了相当一致的间隔:

String appending conversion took 1153ms.
String appending conversion took 1095ms.
String appending conversion took 1081ms.
于 2012-11-28T23:32:50.280 回答