web-dev-qa-db-ja.com

C#のforおよびwhileループ

for (i=0 ; i<=10; i++)
{
    ..
    ..
}

i=0;
while(i<=10)
{
    ..
    ..
    i++;
}

Forループとwhileループのどちらが優れているか、パフォーマンスの面で?

(更新)実際-for構造がより効率的であるシナリオが1つあります。配列をループします。コンパイラ/ JITには、このシナリオ用に最適化されています使用している限りarr.Length条件付き

for(int i = 0 ; i < arr.Length ; i++) {
    Console.WriteLine(arr[i]); // skips bounds check
}

この非常に特殊なケースでは、境界チェックがスキップされます。これは、境界外になることは決してないことをすでに知っているためです。興味深いことに、arr.Lengthを「持ち上げ」て手動で最適化しようとすると、これが発生するのを防ぐことができます。

int len = arr.Length;
for(int i = 0 ; i < len ; i++) {
    Console.WriteLine(arr[i]); // performs bounds check
}

ただし、他のコンテナ(List<T>など)では、手動のマイクロ最適化として、巻き上げはかなり合理的です。

(更新終了)


どちらでもない。とにかく、forループは内部でwhileループとして評価されます。

たとえば、ECMA 334(明確な割り当て)の12.3.3.9は、forループを指示しています。

for ( for-initializer ; for-condition ; for-iterator ) embedded-statement

本質的に同等です(明確な割り当ての観点から(「コンパイラはこのILを生成する必要があります」と言うのとはまったく同じではありません)):

{
    for-initializer ;
    while ( for-condition ) {
        embedded-statement ;
        LLoop:
        for-iterator ;
    }
}

forステートメントを対象とするcontinueステートメントは、ラベルLLoopを対象とするgotoステートメントに変換されます。 for-conditionがforステートメントから省略されている場合、明確な割り当ての評価は、上記の展開でfor-conditionがtrueに置き換えられたかのように進行します。

さて、これはコンパイラがまったく同じことをしなければならないという意味ではありませんが、実際にはほとんどそうです...

46
Marc Gravell

それらは同じであり、とにかくそのようなマイクロ最適化を行うべきではないと思います。

12
Alex Reitbort

パフォーマンスは同じになります。ただし、ループの外側でi変数にアクセスする必要がない限り、forループを使用する必要があります。 iはブロック内のスコープしか持たないため、これはよりクリーンになります。

6
Adam Ralph

プログラムの効率は、適切なアルゴリズム、優れたオブジェクト設計、スマートプログラムアーキテクチャなどから得られます。

Forループとwhileループを使用して1〜2サイクルをシェービングしても、遅いプログラムが速くなったり、速いプログラムが遅くなったりすることはありません。

このセクションでプログラムのパフォーマンスを向上させたい場合は、ループを部分的に展開する方法( Duff's Device を参照)、またはループ内で実行されるパフォーマンスを向上させる方法を見つけてください。

4
abelenky

どちらでもない。それらは同等です。 'for'ループは、whileループを記述するためのよりコンパクトな方法であると考えることができます。

2
Ferdinand Beyer