簡體   English   中英

Java for 循環與 while 循環。 性能差異?

[英]Java for loop vs. while loop. Performance difference?

假設我有以下代碼,有三個 for 循環來做某事。 如果我將最外層的 for 循環更改為 while 循環,它會運行得很快嗎? 謝謝~~

int length = 200;
int test = 0;
int[] input = new int[10];

for(int i = 1; i <= length; i++) {
    for (int j = 0; j <=length - i; j++) {
        for (int k = 0; k < length - 1; k++) {
            test = test + input[j + k];
        }
    }
}

不,更改循環類型無關緊要。

唯一可以使它更快的方法是減少嵌套循環,並循環使用更少的值。

for循環和while循環之間的唯一區別是定義它們的語法。 根本沒有性能差異。

int i = 0;
while (i < 20){
    // do stuff
    i++;
}

是相同的:

for (int i = 0; i < 20; i++){
    // do Stuff
}

(實際上 for 循環要好一些,因為循環后i將超出范圍,而i將留在while循環中。)

for 循環只是一種語法上更漂亮的循環方式。

這種微優化毫無意義。

  • while 循環不會更快。
  • 循環結構不是你的瓶頸。
  • 首先優化你的算法。
  • 更好的是,不要先優化。 只有在您發現算法中確實存在不依賴於 I/O 的瓶頸后才進行優化。

有人建議測試whilefor循環,所以我創建了一些代碼來測試 while 循環或 for 循環是否更快; 平均而言,超過 100,000 次測試, while循環在大約 95% 的時間內更快。 我可能編碼不正確,我對編碼很陌生,還考慮到如果我只運行了 10,000 次循環,它們最終的運行持續時間相當均勻。

編輯當我去測試更多試驗時,我沒有改變所有的數組值。 修復了它,以便更輕松地更改您運行的試驗次數。

import java.util.Arrays;

class WhilevsForLoops {

 public static void main(String[] args) {

final int trials = 100; //change number of trials
final int trialsrun = trials - 1;

boolean[] fscount = new boolean[trials]; //faster / slower boolean
int p = 0; // while counter variable for for/while timers



while (p <= trialsrun) {
     long[] forloop = new long[trials];
     long[] whileloop = new long[trials];

     long systimeaverage; 
     long systimenow = System.nanoTime();
     long systimethen = System.nanoTime();

     System.out.println("For loop time array : ");
     for (int counter=0;counter <= trialsrun; counter++) {
         systimenow = System.nanoTime();
         System.out.print(" #" + counter + " @");
         systimethen = System.nanoTime();
         systimeaverage = (systimethen - systimenow);
         System.out.print( systimeaverage + "ns |");

         forloop[counter] = systimeaverage; 
     }

     int count = 0;
     System.out.println(" ");
     System.out.println("While loop time array: ");
     while (count <= trialsrun) {
         systimenow = System.nanoTime();
         System.out.print(" #" + count + " @");
         systimethen = System.nanoTime();
         systimeaverage = (systimethen - systimenow);
         System.out.print( systimeaverage + "ns |");

         whileloop[count] = systimeaverage;
         count++;
     }


     System.out.println("===============================================");
     int sum = 0;

     for (int i = 0; i <= trialsrun; i++) {
        sum += forloop[i];
     }

     System.out.println("for loop time average: " + (sum / trials) + "ns");

     int sum1 = 0;

     for (int i = 0; i <= trialsrun; i++) {
         sum1 += whileloop[i];
     }
     System.out.println("while loop time average: " + (sum1 / trials) + "ns");



     int longer = 0;
     int shorter = 0;
     int gap = 0;

     sum = sum / trials;
     sum1 = sum1 / trials; 

     if (sum1 > sum) {
        longer = sum1;
        shorter = sum;
     }
     else {
        longer = sum;
        shorter = sum1;
     }

     String longa;

     if (sum1 > sum) {
        longa = "~while loop~";
     }
     else {
         longa = "~for loop~";
     }

     gap = longer - shorter; 
     System.out.println("The " + longa + " is the slower loop by: " + gap + "ns");
     if (sum1 > sum) {
     fscount[p] = true; }
     else {
         fscount[p] = false;
     }
     p++;
}

    int forloopfc=0;
    int whileloopfc=0;

    System.out.println(Arrays.toString(fscount));

    for(int k=0; k <= trialsrun; k++) {
        if (fscount[k] == true) {
            forloopfc++; }
            else {
                whileloopfc++;}

    }

    System.out.println("--------------------------------------------------");

    System.out.println("The FOR loop was faster: " + forloopfc + " times.");
    System.out.println("The WHILE loop was faster: " + whileloopfc + " times.");
 }

}

您無法通過將其更改為 while 來優化它。

你可以通過改變線路來非常非常非常非常小地增加速度

for (int k = 0; k < length - 1; k++) {

經過

for (int k = 0; k < lengthMinusOne; k++) {

其中 lengthMinusOne 之前計算過

這個減法只是計算幾乎 (200x201/2) x (200-1) 次,對於計算機來說是非常少的數字:)

這是一篇關於此事的文章的有用鏈接

根據它,While 和 For 幾乎快兩倍,但兩者都是相同的。

但是這篇文章是在 2009 年寫的,所以我在我的機器上試了一下,結果如下:

  • 使用 java 1.7:迭代器比 For 和 While(仍然相同)快約 20%-30%
  • 使用 java 1.6:迭代器比 For 和 While(仍然相同)快約 5%

所以我想最好的辦法就是在你自己的版本和機器上計時,然后得出結論

即使 while 循環比 for 循環更快的假設是正確的(事實並非如此),您必須更改/優化的循環不會是外部循環而是內部循環,因為這些循環執行的次數更多.

for 和 while 之間的區別在於語義

  • 在 while 循環中,只要條件為真,您就會循環,這可能會有很大差異,因為您可能會在循環中修改用於評估 while 條件的變量。
  • 通常,在 for 循環中,循環 N 次。 這個 N 可以是變量,但直到 N 循環結束時才會移動,因為通常開發人員不會修改在循環條件中評估的變量。

這是一種幫助他人理解您的代碼的方式。 您沒有義務不修改 for 循環變量,但這是一種常見(且良好)的做法。

不,您仍然循環完全相同的次數。 根本沒有關系。

看看你的算法! 您是否事先知道數組中的哪些值被添加了多次?

如果您知道可以減少循環次數,從而提高性能。

有沒有人這樣試過...

int i = 20;
while (--i > -1){
    // do stuff
}

相比:

for (int i = 0; i < 20; i++){
    // do Stuff
}

不會有性能差異。 試試看!

JVM 以及編譯器會將兩個循環都變成類似

    label:
       ;code inside your for loop.
    LOOP label

僅當您使用多線程或多處理器編程時才重要。 然后它還取決於您如何將循環分配給各種處理器/線程。

不,這不會有太大的不同,唯一的問題是,如果您可能出於組織目的考慮切換嵌套循環,則可能希望在外部使用 while 循環並在其中使用 for 語句。 這不會影響性能,但只會使您的代碼看起來更清晰/有條理

你可以自己計算。

int length = 200;
int test = 0;
int[] input = new int[10];

long startTime = new Date().getTime();

for(int i = 1; i <= length; i++) {
    for (int j = 0; j <=length - i; j++) {
        for (int k = 0; k < length - 1; k++) {
            test = test + input[j + k];
        }
    }
}

long endTime = new Date().getTime();
long difference = endTime - startTime;
System.out.println("For - Elapsed time in milliseconds: " + difference);


test = 0;
input = new int[10];

int i = 0, j = 0, k = 0;

startTime = new Date().getTime();

while(i < length) {
    while(j <= length - i ) {
        while(k < length - 1) {
            test = test + input[j + k];
            k++;
        }
        j++;
    }
    i++;
}

endTime = new Date().getTime();
difference = endTime - startTime;
System.out.println("While - Elapsed time in milliseconds: " + difference);

for循環和while循環都是迭代語句,但都有各自不同的特點。

句法

While 循環

//setup counter variable
int counter = 0;

while ( condition) {

    //instructions 

    //update counter variable
    counter++;  //--> counter = counter + 1;

}

For循環

for (initialization; condition; iteration){
    //body of for loop
}

for循環的所有聲明(初始化、條件、迭代)都在循環體的頂部。 相反,在while循環中,只有初始化和條件位於循環體的頂部,並且迭代可以寫在循環體的任何位置。

for 和 while 循環之間的主要區別

  1. for循環中,初始化、條件檢查以及迭代變量的遞增或遞減僅在循環語法中明確完成。 相反,在While循環中,我們只能在循環的語法中初始化和檢查條件。

  2. 當我們知道循環執行中必須發生的迭代次數時,我們使用 for 循環。 另一方面,如果我們不知道循環中必須發生的迭代次數,那么我們使用while循環。

  3. 如果沒有將條件語句放入for循環中,則會導致循環無限迭代。 相反,如果在while循環中沒有放入條件語句,則會導致編譯錯誤。

  4. for循環語法中的初始化語句僅在循環開始時執行一次。 相反,如果while循環在其語法中帶有初始化語句,則 while 循環中的初始化語句將在每次循環迭代時執行。

  5. for循環中的迭代語句將在for循環體執行后執行。 相反,迭代語句可以寫在while循環體中的任何位置,因此,在 `while 循環體中可以有一些語句在執行完迭代語句之后執行。

基於此: https : //jsperf.com/loops-analyze (不是我創建的)while 循環通常比 for 循環慢 22%。 至少在 Javascript 中是這樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM