2013-08-02 31 views
2

使用java嘗試解決數學問題,並尋找提高解決方案效率的方法,我得到了一個執行時間非常大的增加,並不知道它是如何來的。經過幾次測試後,我可能找到了答案,但我仍然不知道如何或爲何發生這種情況。數組聲明內部方法與數組在時間上的區別在方法外部聲明並在內部用作輸入

下面是測試代碼,顯示這個時間差:

public class arrayAcessTime { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 

     AccessTime(); 
    } 

    public static long getLargestPrimeFactor(long l, int[] x) 
    { 
     long p = 0, n = l/2, r = (long) Math.sqrt(l), y = 49; 

     for(long i = 13; i <= r;) 
     { 
      for(int j = 0; j<x.length; j++) 
      { 
       if (l % i == 0) 
       { 
        n = l/i; 
       } 

       else 
       { 
        n = l/(i + 1); 
       } 

       i+=x[j]; 
      } 
     } 

     return p; 
    } 

    public static long getLargestPrimeFactor(long l) 
    { 
     long p = 0, n = l/2, r = (long) Math.sqrt(l), y = 49; 

    int x[] = {2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2,   

     System.out.println("x size: " + x.length); 

     for(long i = 13; i <= r;) 
     { 
      for(int j = 0; j<x.length; j++) 
      { 
       if (l % i == 0) 
       { 
        n = l/i; 
       } 

       else 
       { 
        n = l/(i + 1); 
       } 

       i+=x[j]; 
      } 
     } 

     return p; 
    } 

    public static void AccessTime() { 

     int array2[] = {2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2,....} //too large to write here 


     long start; 
     double diff; 

     System.out.println("Array2 size: " + array2.length); 

     start = System.currentTimeMillis(); 

     getLargestPrimeFactor(8798765600851475143L, array2); 

     diff = (System.currentTimeMillis() - start)/1000.0; 

     System.out.println("Time: " + diff); 


     start = System.currentTimeMillis(); 

     getLargestPrimeFactor(8798765600851475143L); 

     diff = (System.currentTimeMillis() - start)/1000.0; 

     System.out.println("Time: " + diff); 

    } 
} 

輸出:

Array2 size: 5760 
Time: 6.144 
x size: 5760 
Time: 30.225 

正如你可以看到時間的增加是非常顯著(約5倍)。這兩種方法幾乎相同,只是其中一個數組已初始化,另一個將初始化數組作爲輸入。如何或爲什麼這會導致時間的顯着增加?另一方面,對於相當小的陣列(< 500),我沒有注意到任何值得注意的區別。所以,在我看來,只有更大的陣列受到這個影響。這是否更好地在方法外部初始化數組,並將其作爲方法的輸入而不是在裏面聲明?這對其他語言是否一樣?最好的方法是什麼或取決於情況?非常感謝!

+1

@Mysticial:該方法雖然只被調用一次。 –

+0

減少的時間是因爲您沒有包括在定時中初始化陣列需要多長時間。該數組在被定時的代碼部分之外被初始化。 –

+0

@KevinCrowell:雖然這是正確的,但我不希望它需要24秒來初始化數組... –

回答

0

我有一個hunch - 但它只是一個預感,它仍然令人驚訝。

這是一個相對長期運行的方法 - 所以Hotspot可能會多次對它進行JIT編譯,應用越來越多的優化。

您的第一個方法的字節碼非常短,所以快速打印它。但是,第二種方法的字節碼將是巨大的 - 這可能意味着大部分時間都花費了JITting。

您可以通過多次運行每種方法並打印每次迭代需要多長時間來驗證這一點 - 我期望每種方法的「遲到」運行需要大約相同的時間。如果這佔了全部的區別(我期望JIT優化初始化字節碼一次,然後忽略它),但是這至少是值得測試的。

+0

好吧,我在c#中嘗試了類似的代碼,大概同時得到了17個,所以最有可能與java相關,因爲它比第二個可以更快地通過第一個。它仍然很高興看到這一點,充分利用一種語言不能沒有體驗它的經驗。謝謝。 – mj1261829

相關問題