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% 遅くなります。ほとんどの場合、2 番目の呼び出しは 3 番目の呼び出しよりもわずかに遅くなります。

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

Just-in-time (JIT) コンパイラは、コードをオンザフライでプロファイリングし、実行を最適化します。コードが頻繁に実行されるほど、最適化されます。

たとえば、詳細については、次の質問を参照してください: (How) 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 に答える