2012-03-23 1 views
2

以下の編集を参照してくださいjava jdk 1.7 64ビットでは、intを使用するforループはforループよりも20倍以上高速です。どうして?

終了チェックで進行中のキャスティングはありません。私は<と++が64ビットマシン上でintとlongで高速になると思います。しかし、私はないと思いますか?

INT:65ミリ秒:

public void testWTF() throws Exception { 
    int runs = 10; 
    long hs = 0; 
    long timeSum = 0; 
    for (int run = 0; run < runs; run++) { 
     int term = Integer.MAX_VALUE; 
     long start = System.currentTimeMillis(); 
     // ***** loop to be tested ****** 
     for (int i = 0; i < term; i++) { 
      hs++; 
     } 
     timeSum += (System.currentTimeMillis() - start); 
     System.out.println("hs = " + hs); 
     hs = 0; 

    } 
    System.out.println("timeSum = " + timeSum); 
    System.out.println("avg time = " + (timeSum/runs) + " for " + runs + " runs"); 
    System.out.println("hs = " + hs); 
} 

長い:1445ミリ秒

public void testWTF() throws Exception { 
    int runs = 10; 
    long hs = 0; 
    long timeSum = 0; 
    for (int run = 0; run < runs; run++) { 
     long term = Integer.MAX_VALUE; 
     long start = System.currentTimeMillis(); 
     // ***** loop to be tested ****** 
     for (long i = 0; i < term; i++) { 
      hs++; 
     } 
     timeSum += (System.currentTimeMillis() - start); 
     System.out.println("hs = " + hs); 
     hs = 0; 

    } 
    System.out.println("timeSum = " + timeSum); 
    System.out.println("avg time = " + (timeSum/runs) + " for " + runs + " runs"); 
    System.out.println("hs = " + hs); 
} 

ハードウェア:64ビットXeonプロセッサは、Windows 7の64ビット版を実行しています。

編集:これをいくつかの繰り返しに変更しました。 intバージョンで100万回実行する場合、平均時間は65ミリ秒です。ロングバージョンは100万回、1000回、さらには100回も長くかかります。10回の実行では、平均時間は1447ミリ秒です。

また、私はループの外側にhsを使用しているので、ループが邪魔にならないようにしています。

+1

これを複数回実行しましたか?あなたが一度それを実行した場合、それは巨大な時差を説明することができます。 –

+1

結果を確認できません。 intバージョンiでは、平均時間は1475msで、ロングバージョンは1463msで10回実行されます。 JDK 7のアップデートでWindows 8 64ビットで実行64ビット – Henry

答えて

3

これはベンチマークを行うのが非常に悪い/信頼できない/非現実的な方法です.JITは実際には多くの最適化を行う機会がないため、ベンチマークを一度だけ実行し、最初の実行を測定します。

基本的に、JavaのJITは、コードが広範囲に使用されるのを見て、コードを大幅に最適化します。実際のプログラムでは、JITはクリティカルループを最適化するため、現実の世界を模倣するベンチマークが必要な場合は、JITを納得させる必要があります。

Javaで正確なベンチマークを取得する最も簡単な方法Caliperのようなツールを使用して、JITを適切にウォーミングアップして正確な測定値を得る方法を知り、結果がより一貫しているかどうかを確認することです。

+0

上記の編集を参照してください。 – marathon

+0

JITは、ループ全体を 'hs = term'という代入で置き換えるだけで、' int'に対してループを完全に排除するほどスマートです。バイトコードは 'long'の方が複雑です。おそらく、JITはそのような場合にはスマートではないことを示しています。いずれにしても、現実的なベンチマークではありません。 –

+0

これを少し修正して、hsをループ外で使用する必要があります。それはintの約65msを与える。 – marathon

関連する問題