あな性能差のために()と()?
-
21-08-2019 - |
質問
ているのか、あるいは全て意味論?
解決
答え:いや、でも全く同じです。
推測できる理論のコンパイラ;本当に折れたものも若干異なるがん驚いて頂きたいと思っています。
楽しいこちらの二つの異ることをコンパイルを同じ組み立てコードを活用していることからもx86gcc版4.3.3として同梱されUbuntu.で確認することができ組み立て生産されて最終的なバイナリと objdump プログラムを利用しています。.
int main() { #if 1 int i = 10; do { printf("%d\n", i); } while(--i); #else int i = 10; for (; i; --i) printf("%d\n", i); #endif }
編集: ここでは"みかんとオレンジ"whileる例も統を同じことを
while(i) { printf("%d\n", i); --i; }
他のヒント
、コンパイラによって生成されたマシンコードは(ほぼ)同じである必要があります。
たとえば、私が数年前にやったいくつかのテストでは、
for (int i = 0; i < 10; i++)
{
...
}
と
int i = 0;
do
{
...
i++;
}
while (i < 10);
まったく同じコードを生成する、または(とニールはコメントで指摘)を心配する性能が十分に大きな違いをすることはありません1つの余分JMP、となります。
ありません意味の違いが必要なとめます。により異なりますがコンパイラです。ましたが、かっこいい、g++4.3.2、CC5.5xlc6.
g++、CCた、xlcませんでした
の違いxlcの初期ループに入力します。
extern int doit( int );
void loop1( ) {
for ( int ii = 0; ii < 10; ii++ ) {
doit( ii );
}
}
void loop2() {
int ii = 0;
while ( ii < 10 ) {
doit( ii );
ii++;
}
}
XLC出力
.loop2: # 0x00000000 (H.10.NO_SYMBOL)
mfspr r0,LR
stu SP,-80(SP)
st r0,88(SP)
cal r3,0(r0)
st r3,64(SP)
l r3,64(SP) ### DIFFERENCE ###
cmpi 0,r3,10
bc BO_IF_NOT,CR0_LT,__L40
...
enter code here
.loop1: # 0x0000006c (H.10.NO_SYMBOL+0x6c)
mfspr r0,LR
stu SP,-80(SP)
st r0,88(SP)
cal r3,0(r0)
cmpi 0,r3,10 ### DIFFERENCE ###
st r3,64(SP)
bc BO_IF_NOT,CR0_LT,__La8
...
while
ループの試験における変数のスコープはfor
ループのヘッダで宣言された変数の範囲よりも広くなっている。
そこで、次に、ループの一方との間で選択(及びでしばらくアップラップしないでパフォーマンスへの影響があるでしょう{}低減しますその変数のスコープ)。
の例では、それを参照するイテレータの数をカウント同時コレクションかもしれない、そして、複数の反復子が存在する場合のみ反復子がそれを参照する場合、それは同時変更を防止するためにロック適用されますが、最適化のようにロックをelides 。あなたはその後、同じコンテナに異なる名前のイテレータを使って関数内の2つのfor
ループを持っていた場合、ファストパスが取られますが、2 while
と遅いパスが取られることになるループされるだろう。同様に存在オブジェクトは(複数のキャッシュトラフィック)大きい場合、パフォーマンスに影響すること、またはシステムリソースを使用することができます。しかし、私はそれが違いを生むだろう、私が今まで見た実際の例を考えることはできません。
コンパイラは、おそらく唯一のforループの場合にはそうなります。
はどちらも同じです。これは、意味論の問題です。
あなたが構造、のの後に体までの状態の評価を延期し、したがって1つの評価を保存することがあります。どこながら唯一の違いは...やるにあるのかもしれません
i = 1; do { ... i--; } while( i > 0 );
とは対照的に
for( i = 1; i > 0; --i )
{ ....
}
私はコンパイラを書きます。私たちは、条件付きと無条件分岐にすべての "構造化" の制御フロー(if
、while
、for
、switch
、do
... while
)をコンパイルします。その後、我々は、制御フローグラフを分析します。 Cコンパイラは、とにかく一般goto
に対処する必要があるので、それはその後、ブランチ、条件分岐命令をするののすべてを減らすだけでなく、その場合に対処するようにしてくださいするのが最も簡単です。 (Cコンパイラは、手書きのコードではなく、多くの、多くのgoto
文を持っていることも、上に自動的に生成されたコードだけでなく、良い仕事をする必要があります。)
はありません。彼らは同等のものをやっている場合、それらは同じコードにコンパイルします - あなたが言うように、それは意味論についてです。最高のは、あなたが表現しようとしているものを表すいずれかを選択します。
理想的には同じである必要がありますが、最終的にそれはあなたのコンパイラ/インタプリタに依存します。確かに、あなたは、生成されたアセンブリコードを測定するか、調べる必要があります。
これらの線はcc65を使用して異なるアセンブリコードを生成する:違いがあるかもしれないことを証
for (; i < 1000; ++i);
while (i < 1000) ++i;
のAtmel ATMEGA上にある間()は()よりも高速です。なぜこれはAVR035で説明されている:AVRのための効率的なCコーディング
P.S。オリジナルプラットフォームが問題に言及していませんでした。
に引き続きと のしばらくのに異なる動作をします: にのために、それは<強い中、カウンタを変更>しばらくの、それは通常しない
を追加する答え:私の経験を最適化するソフトウェアは、ふさふさひげて削る。
- まずはロプ-ノールで大きな塊をハサミ(プ全体肢の話。
- それまでの短い電動クリッパー(調整アルゴリズム).
- その髭そりとカミソリなんの少し低レベルの最適化。
最後の場所の違い for()
や while()
ができなかったが、おそらくいく。
P.S.のプログラマが知っているすべての非常に良いと疑いは代表的なサンプル)を基本に行くものです。
彼らは、限りのパフォーマンスが行くのと同じです。離散的なオブジェクトの数を処理する場合(例えば、コレクション内の各アイテムを通過するように)while
(例えば充填するバッファを待っているような)状態変化を待っているとき、私はfor
を使用する傾向がある。
いくつかのケースでは違いがあります。
あなたはその違いが重要ポイントである場合は、、あなたはどちらか、より良いアルゴリズムを選択するか、アセンブリ言語でコーディングを開始する必要があります。アセンブリでコーディングすることは、あなたのコンパイラのバージョンを固定することが好ましい、私を信頼しています。
は while()
高速-減速比 for()
?ューにいくつかの最適化について:
コンパイラの作成者はしっかり働いてくれてい削サイクルタイムな通話にジャンプの比較、増加、その他の種類の指示をするものを生成する際に使われます。
電話指示一方、消費の多くの大きさよりサイクルが、コンパイラはほぼ無力なものを削除します。
としてのプログラム開発においては多くの関数呼び出しは、こうあがいを怠り、一部のコンパイラの伝票していることなく自明である。
ほとんどの時間でもかまわないので、ハードウェアが早いので、私たちの仕事では非常に少ないことがわかるコンピュータのようなビーグル犬のたwolfes彼女の食品およびヒにあります。
もし、仕事が大きな性能である。
いうのか。この大きな利得?
- のコンパイラの削りだ少数のサイクルオイル&ょうか?
- 発見の機能のない -本当に- 必要となる場合があるのですか?
のコンパイラはできないの後になります。私たちだけのプログラマです。
我々は教えるべきかではないかと思います。できません。まcongenitally傾斜めに間違った推測し、そのベットです。良アルゴリズムが始まりですが始まります。当社の教師に教えることがあ その 知。
プロファイラーは始まります。 います。
のapocryphal見積もりのウィリーサットンまた なぜrob銀行?:
ることは、お金です。
保存したい場合はサイクルを見たとされにくくなります。
かどうかをコーディングスタイル.
- ただの反復回数.
- ができない場合は、反復回数.