0

データ型「int」と「long」のパフォーマンスを比較しようとすると、この奇妙な問題が発生します。基本的に、2 つの単体テストがあります。

@Test
public void testLongOperationPerformance(){
    StopWatch sw = new StopWatch();
    sw.start();
    long count = 0l;
    for(int i = 0; i < Integer.MAX_VALUE; i ++){
        count++;
    }
    sw.stop();
    System.out.println(count);
    System.out.println(sw.elaspedTimeInMilliSeconds());
}

@Test
public void testIntegerOperationPerformance(){
    StopWatch sw = new StopWatch();
    sw.start();
    int count = 0;
    for(int i = 0; i < Integer.MAX_VALUE; i ++){
        count++;
    }
    sw.stop();
    System.out.println(count);
    System.out.println(sw.elaspedTimeInMilliSeconds());
}

これら 2 つの単体テストは同じことを行っています。違いは、一方はカウンターのデータ型として int を使用し、もう一方はそのために long を使用することです。結果:

jdk6u32 (64 bit):
test with long
2147483635
96
test with int
2147483647
2

jdk7 (64 bit)
test with long
2147483647
1599
test with int
2147483647
1632

私は気づきました:

  1. jdk6u32 では、int を使用したテストは long を使用したテストよりもはるかに高速です
  2. jdk6u32で、intを使ったテストとlongを使ったテストでテスト結果が違う
  3. jdk7 では、両方のテストの速度はほぼ同じですが、どちらも jdk6u32 よりもはるかに遅いです。
  4. jdk7では、両方のテストで同じ結果が得られました

なぜそうなのか、誰か説明できますか?

4

1 に答える 1

6

Java JIT は、何もしないコードを排除するのに特に優れています。あなたの例では、ループ

long count = 0l;
for(int i = 0; i < Integer.MAX_VALUE; i ++){
    count++;
}

で置き換えることができます

long count = 0l;
count += Integer.MAX_VALUE * 1;

タイミングを計っているのは、ループを検出して削除するのにかかる時間です。この時間は、以前に行ったことに依存する可能性があるため、ループを別の順序でテストして、結果が変わるかどうかを確認することをお勧めします.

Java 6 & 7 では、多くのループ最適化が正しく最適化されていませんでした。

例: この無限ループは、更新によっては必ずしも無限ではありませんでした

for(int i=0; i < Integer.MAX_VALUE; i += 2)

このため、一部の更新では、そのバージョンで機能したかどうかに応じて、最適化のオンとオフが異なります。Java 7 の最新バージョンを試して、違いがあるかどうかを確認することをお勧めします。

于 2012-08-30T05:45:41.577 に答える