web-dev-qa-db-ja.com

Java forループとwhileループ。パフォーマンスの違いは?

私が次のコードを持っていると仮定すると、何かを行うための3つの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];
        }
    }
}
26
KKLong

いいえ、ループのタイプを変更しても問題ありません。

高速化できる唯一の方法は、ループのネストを少なくし、より少ない値でループすることです。

forループとwhileループの唯一の違いは、それらを定義するための構文です。パフォーマンスの違いはまったくありません。

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

次と同じです:

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

(実際にforループは、iがループ後にスコープ外になり、iwhileループの場合に留まるため、少し改善されます。)

Forループは、構文的にきれいなループ方法です。

55
jjnguy

この種のマイクロ最適化は無意味です。

  • Whileループは速くなりません。
  • ループ構造はnotボトルネックです。
  • 最初にアルゴリズムを最適化します。
  • さらに良いことに、最初に最適化しないでください。 I/Oに依存しないアルゴリズムのボトルネックが本当にあることがわかった後にのみ最適化してください。
31
Bombe

whileに変更して最適化することはできません。

ラインを変更することで、速度を非常に非常にわずかに増加させることができます

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

沿って

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

ここで、lengthMinusOneは前に計算されます

この減算は、ほぼ(200x201/2)x(200-1)回を計算しているだけで、コンピューターにとっては非常に少ない数です:)

10
ufukgun

誰かが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.");
 }

}
7
Sleepy

Whileループがforループよりも高速であるという仮説が真(そしてそうではない)であったとしても、変更/最適化が必要だったループは外側のループではなく、内側のループになります。 。

2
fortran

Forとwhileの違いはsemanticです:

  • Whileループでは、条件がtrueである限りループします。これは、ループ内でwhile条件の評価に使用して変数を変更する可能性があるため、大きく変化する可能性があります。
  • 通常、forループでは、N回ループします。このNは変数にすることができますが、通常、開発者はループ条件で評価される変数を変更しないため、Nループの終わりまで移動しません。

他の人があなたのコードを理解するのを助ける方法です。ループ変数を変更しない義務はありませんが、それは一般的な(そして良い)習慣です。

2

ここに役立つ link 問題の記事へ

それによると、WhileとForはほぼ2倍高速ですが、どちらも同じです。

[〜#〜] but [〜#〜]この記事は2009年に書かれたので、自分のマシンで試してみました。結果は次のとおりです。

  • Java 1.7:イテレータはFor and While(まだ同じでした)よりも約20%-30%高速でした)
  • Java 1.6:イテレータはForとWhileよりも約5%高速でした(まだ同じでした)

だから私は最高のことはあなた自身のバージョンとマシンでちょうどそれを時間を計ることであると思います

2
levtatarov

いいえ、まだまったく同じ回数ループしています。まったく問題ではありません。

1
aquinas

アルゴリズムを見てください!配列のどの値が複数回追加されるかを事前に知っていますか?

ループの数を減らすことができ、パフォーマンスが向上することがわかっている場合。

1
Roalt

誰もがこのように試しましたか...

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

に比べ:

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

これに基づいて: https://jsperf.com/loops-analyze (私は作成していません)whileループは、一般的なforループより22%遅いです。少なくともJavascriptではそうです。

0
Arash R

パフォーマンスの違いはありません。やってみよう!

JVM、さらにコンパイラーは、両方のループを次のようにします

    label:
       ;code inside your for loop.
    LOOP label
0
Adrian

マルチスレッドまたはマルチプロセッサのプログラミングを使用している場合にのみ問題になります。また、ループをさまざまなプロセッサ/スレッドに割り当てる方法にも依存します。

0
Extrakun