2014-12-04 82 views
1

對於一個簡單的多線程的代碼,如下所示,爲什麼計算需要更長時間的文字?

它需要41338 milliseconds於具有類似延遲

關閉主線程,始終如一地,如果我與int替換long,和比較等i < 0x7FFFFFFF它需要28 milliseconds始終與類似的延遲。

機功率:DELL E6430緯度上運行64位JVM 1.6

public class Dummy { 

    private static int NUM_OF_THREADS=200; 

    private static Thread[] thread = null; 

    public static void loopSomeTime(int i) { 
     thread[i] = new Thread(new Runnable(){ 
      public void run(){ 
       int count = 0; 
       for(long i = 0; i < 0x7FFFFFFFL; ++i){ 
        count++; 
       } 
       System.out.println(count); 
      } 
     }); 
     thread[i].start(); 

    } 


    public static void main(String[] args) throws InterruptedException{ 
     thread = new Thread[NUM_OF_THREADS]; 
     long beginTime = System.nanoTime(); 

     for(int i =0; i < NUM_OF_THREADS ; i++){ 
      loopSomeTime(i); 
     } 
     //I need to wait here 

     for(Thread eachThread : thread){ 
      eachThread.join(); 
     } 

     long endTime = System.nanoTime() - beginTime; 
     System.out.println("Time taken: " +endTime/(1000*1000) + " milliseconds"); 
    } 
} 

我解釋的0x7FFFFFFFL等值64位機的價值0x7FFFFFFF作比較,這是2147483647

請幫助我瞭解延遲的差異。

+7

這是不是一個有用的做標杆的方法;你的數字將遠離真實的表現。您需要擔心諸如JIT熱身等類似事情,實際上這意味着要使用精心設計的基準測試工具,如Caliper或JMH。你不能從你正在做的測量類型中得到任何有用的數字。 – 2014-12-04 19:48:11

+0

你確定你沒有意外地在那裏多加一個F嗎? – Daniel 2014-12-04 19:48:36

+0

另外,如果你跑了兩次程序,有可能第二次跑得更快 – Daniel 2014-12-04 19:49:08

回答

4

的代碼是不一樣的...... 這裏是int版本的代碼:

public void run(); 
    Code: 
     0: iconst_0 
     1: istore_1 
     2: iconst_0 
     3: istore_2 
     4: iload_2 
     5: ldc   #2     // int 2147483647 
     7: if_icmpge  19 
     10: iinc   1, 1 
     13: iinc   2, 1 
     16: goto   4 
     19: getstatic  #3     // Field java/lang/System.out:Ljava/io/PrintStream; 
     22: iload_1 
     23: invokevirtual #4     // Method java/io/PrintStream.println:(I)V 
     26: return 
} 

這裏是long版本的代碼:

public void run(); 
    Code: 
     0: iconst_0 
     1: istore_1 
     2: lconst_0 
     3: lstore_2 
     4: lload_2 
     5: ldc2_w  #2     // long 2147483647l 
     8: lcmp 
     9: ifge   22 
     12: iinc   1, 1 
     15: lload_2 
     16: lconst_1 
     17: ladd 
     18: lstore_2 
     19: goto   4 
     22: getstatic  #4     // Field java/lang/System.out:Ljava/io/PrintStream; 
     25: iload_1 
     26: invokevirtual #5     // Method java/io/PrintStream.println:(I)V 
     29: return 
} 

你可以觀察到JVM使用的說明不一樣。 int s遞增,而long s使用算術。粗略地說:int代碼使用寄存器而不是long之一。

這解釋了至少在我的電腦上,也可能是你的差異。

它用java:

java version "1.8.0_20" 
Java(TM) SE Runtime Environment (build 1.8.0_20-b26) 
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode) 

和javac

javac 1.8.0_20 

上的MacOSX 10.9平臺

我的JVM是64位...

+0

但是請注意,一個好的JITC會「消解」大部分的差異。 – 2014-12-04 20:33:25

+1

並注意這是由於int和long之間的差異。 '長*文字*'與它無關。 – EJP 2014-12-04 20:35:07

+0

@EJP - 有一種特殊情況,其中* javac *必須爲「small」long類型文件(例如'5L')執行'ldc2_w',而相應的'int'代碼將執行文字加載與'iconst_5'。 – 2014-12-04 22:47:11

相關問題