2012-03-15 13 views
0

状況によっては、ループ、またはdo-whileループを互換的に使用できます。 私の友人の1人は、このような状況はdo-whileループを使用すべきだと私に言った。 よりも速く、よりも速いためです。 誰も私にそれの証拠を与えることができますか?Cではどのループが速いのですか? whileループまたはdo-whileループ

+0

この議論はありませんでした:http:// stackoverflow。co.jp/q/3347001/694576? – alk

+0

投稿する前に自分自身で重複の有無を確認してください –

答えて

6

両方のループはほとんど同じです(do-whileは少なくとも1回実行されます)。多くの場合、少なくともx86では同じ命令にコンパイルされます。

次のコード:

int main(int argv, char *argc[]) { 
    int a = 0; 
    while (a < 100) { 
     a++; 
    } 
    a = 0; 
    do { 
     a++; 
    }while(a < 100); 
    return 0; 
} 

は、このアセンブリを生成します(gcc -S -o temp.as temp.cを使用して):

_main: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp 
    subl $16, %esp 
    call ___main 
    movl $0, 12(%esp) >> while 
    jmp L2 
L3: 
    addl $1, 12(%esp) 
L2: 
    cmpl $99, 12(%esp) 
    jle L3 
    movl $0, 12(%esp) >> do-while 
L4: 
    addl $1, 12(%esp) 
    cmpl $99, 12(%esp) 
    jle L4 
    movl $0, %eax 
    leave 
    ret 
+0

このコードは、1つの余分な命令 'jmp L2'を使用していることを示しています。たとえそれが1つの命令であったとしても、do-whileはwhileよりも速いと結論づけることができます。 –

+2

一度実行するブランチは、とにかく考えなければならないものではありません。それは遅い要因とみなされることは非常に微妙です。それは最初に起こるだけです。 – MByD

+1

これはマイナーチェンジであり、コードの可読性よりもはるかに重要です – MByD

6

あなたはリンゴと桃を比較しています。

do-whilewhileループは、それらが提供する機能が異なります。
do-whileは常に1回実行され、whileは条件が真である場合にのみ実行されます。

いずれかを使用できる状況では、パフォーマンスの違いはありません。
疑問がある場合は、自分のプラットフォームで自分自身をプロファイリングするか、両方のアセンブリ出力を分析してください。

+0

@Ais私の質問をもう一度読んでください。私はいくつかの状況では、すべての状況を使用することはできないと言いました。 –

+0

@HabeebPerwad:もう一度私の答えを読んでください。特定の第3パラグラフ。 –

1

あなたが別のセマンティック(少なくとも一度対多分なし)気をいけない場合があり、変わりはない。

2

いいえ。C標準は実行速度の要件を提供しないため、一般的に証明することはできません。

+0

最適化されない明白な状況があります。外部関数呼び出しはCライブラリにはありません(コンパイラが '約何かを仮定する)。ループガードが外部コールである場合、一般的に2度呼び出すことは、1度呼び出す場合の約2倍の高価になります。プログラムのパフォーマンス、最適化の効果については、基本的に正しい方向性があります。 – Kaz

+0

@ Kaz:私はあなたの意見を確認するか分からない。特定のプログラムや特定のコンパイラでは、パフォーマンスを予測することが可能であることに同意します。しかし、これは「証明」(HabeebPerwadが求めているように)を構成することはほとんどありません。 – Mankarse

2

whileとdo-whileとの違いは、条件をチェックせずに常に最初の時間を実行することです。したがってと仮定すると、の条件が実際に真である場合、do-whileはこれを保存します条件のチェック。

これはせいぜいマイクロ最適化です。

+0

ループガードは、ループのボディおよび反復回数に対して任意に高価になる可能性があるため、最適化の可能性の上限はありません。 – Kaz

+0

私はそれが1つの命令以上であると信じています。それは1つのブランチしか持たず、他のループは2つです(ブランチを借りたときに1つの条件付きで、最後に無条件で1つの条件付き)ので、コードを最適化する自由をコンパイラに与えます。 – MimSaad

1

C semanticは、最適化の問題が無関係な抽象マシンの動作を記述します。 (C99 Standard、5.1.2.3p1を参照)

1

コンパイラが最適化できる状況であれば、ループはwhileループに従ってください。 Top-of-Loopテストがより明確になりました。その理由は正式な検証に根ざしているからです。 whileループは、本体の正しい実行の前提条件をテストします。 doループは、何もテストせずに本体を一度実行し、その後、対処する必要があります。理由を考えるのはもっと難しいです。私たちは、ループの前に存在していた条件と最初の反復の無防備な実行の結果の結果として状況が何であるかについて考えなければなりません。

ループガードが高価な場合(I/Oを行うことができる外部機能への呼び出しや、他に何が分かっているかなど)、可能であれば、それを下に移動することを検討してください。

関連する問題