1

私の講義では、設計と解析の アルゴリズムでは、講師は、次のサンプルalgoのwhileループwhileループ時間がかかると述べた。Forループ対Whileループ

1. for(int i=0;i<5;i++) 
    {  
2.  print(i);  
    } 

1. int i=0; 
2. while(i<5) 
    {  
3.  print(i);  
4.  i++;  
    } 

彼は、コンパイラは、このようにしながら5回線用の1. 2. 4倍の合計時間+ 4 = 9 を読み取るしかし、whileループの場合であろうと述べました。コンパイラは、1を1回読み込みます。 5回、4回は3回、4回は4回。したがって、合計時間1 + 5 + 4 + 4 = 14時間 この権利は教えてください。 forループはwhileループより速いですか?

ありがとうございました。

+0

速度のためのopmizingに設定されたコンパイラは 'print(i)'を5回だけ発行し、ループを完全に排除するかもしれません。両方の場合において。 – Joey

+0

現実世界では、コードの読みやすさを調べ、それに応じて 'for'または' while'を選択します。コンパイラは、その差を最適化します。あるいは、現代の機械ではその差はごくわずかです。コンピュータの「生活」ではなく、あなたの人生を楽にするものを使用してください。 – Bazzz

+0

、最適化するように設定されていない場合は?? – wali

答えて

6

少なくともMSVC 16(VS 2010)を用いてコードはほとんど同じ両方の場合である:

; Line 5 
    xor esi, esi 
[email protected]: 
; Line 6 
    push esi 
    push OFFSET [email protected][email protected][email protected] 
    call _printf 
    inc esi 
    add esp, 8 
    cmp esi, 5 
    jl SHORT [email protected] 

ため

コードin my Subversion repository

; Line 4 
    xor esi, esi 
[email protected]: 
; Line 6 
    push esi 
    push OFFSET [email protected][email protected][email protected] 
    call _printf 
; Line 7 
    inc esi 
    add esp, 8 
    cmp esi, 5 
    jl SHORT [email protected] 

一方。

+2

* sanity *ありがとうございます。 (デバッグ情報とラベル名だけが異なることに注意してください) –

2

すべての現代コンパイラloop analysisは、より低いレベルの中間表現(すなわち、すべての高レベルループ構成がラベルおよびジャンプに展開される)で行われる。コンパイラでは、両方のループが完全に同等です。

+0

私は彼と議論するためにどのような論理的な理由や証拠を提供することができます。 – wali

+0

@wali、両方のバージョンのアセンブリ出力を表示し、このスライドに 'gcc'または' llvm'(現代のコンパイラの典型的な代表者)の関連する変換実装を示します。 –

2

私はパフォーマンスに渡します:しかし構文メンテナンスに2つの重要な違いがあります(ヒントを証明するために生成されたIRまたはアセンブリをチェックし、違いはありませんが)。

構文

i変数の範囲が異なっています。 while場合には、ループ後に利用可能である間for場合、iは、forヘッダ内でのみアクセス可能です。原則として、範囲が狭く、変数が少ない方が良い飛行機は、コーディング時に心配する文脈が少ないことを意味します。

メンテナンス

forループ操作が一緒に閉じるすべての反復をグループ化するニートという利点を有するので、それらはワンショットで検査等を確認することができます。カウンタはもはや実装されているとして、無限ループ:while場合

for(int i = 0; i != 10; ++i) { 
    if (array[i] == nullptr) { continue; } 
    // act on it 
} 


int i = 0; 
while (i != 10) { 
    if (array[i] == nullptr) { continue; } 
    // act on it 
    ++i; 
} 

continueの導入は、バグを作成しました:

はまた、 continue文を導入する一つの重要な違いはありません。

インパクト

forループが定期反復パターンについて、より読みやすく、すべての周り優れています。さらに良いことに、C++ 11の範囲-のための文で:あなたがいない台無しに確信しているので、反復が完全に、コンパイラによって考慮される

for (Item const& item : collection) { 
} 

! corrolaryでは

を(退却を開始し、それはfor_eachアルゴリズムは多少議論の余地なります...と私たちはフォームの古いを望むことができます):whileループは不規則な繰り返しパターンに予約する必要があり、この方法は、彼らは、コードレビューの際に特別の注意を引き付けると、将来のメンテナーから強調表示不規則性の場合。