GOTO、デバイス上で実行され実行されている間、パフォーマンスに影響しますか?
Objective CでGOTOを使用するのは良い習慣ですか、それとも悪い習慣ですか?
また、GOTO ステートメントを使用するのはどのような場合に適していますか?
ありがとう。
GOTO、デバイス上で実行され実行されている間、パフォーマンスに影響しますか?
Objective CでGOTOを使用するのは良い習慣ですか、それとも悪い習慣ですか?
また、GOTO ステートメントを使用するのはどのような場合に適していますか?
ありがとう。
Agoto
は単なるジャンプであるため、パフォーマンスへの影響は実質的にゼロです。コードの可読性が損なわれるため、これは悪い習慣です。ほとんどの場合、それなしで行うことができます。使用するのが理にかなっているケースのいくつかは、goto
前の質問で説明されています。 goto を検索してください。
go to ステートメントを使用することは通常、特にオブジェクト指向言語 (オブジェクト指向の方法で同じ目的を簡単に達成できる) では悪い習慣ですが、パフォーマンスの観点からではなく、コードの読みやすさの観点からです。 ..
BAD と GOOD プラクティスには何もありません。これは要件次第です。実行したい同じコードがある場合は、ループと言うことができ、使用できますgoto
。ここにこれに関する小さな例があります。これで疑問が解消されると思います。
label
任意の名前を宣言します。ここでhello
は、次のようなステートメントlabel
を使用して呼び出すことができます-goto
hello:
NSLog(@"Print hello!");
goto hello;
これにより、「Print hello!」が出力されます。何回も何回も。
原則として、関数に存在するだけでパフォーマンスに影響を与えるgoto
可能性があります。
パフォーマンスの違いはほとんどの場合目立たないものでありgoto
、オプティマイザーをわずかに混乱させてパフォーマンスに影響を与える可能性がある以外にも多くのことがあります。ただし、興味がある場合は、発行されたコードの違いを調べることができます。
生成されたコードの基本的な要件は、goto[*]のソースとターゲットで同じレジスターを同じものに使用する必要があることです。これにより、コンパイラがコードを最適化するときにレジスタ割り当てが制限されます。このような制約はまったく効果がない可能性があり、処理速度が低下したり、追加のコードが発行されたりする可能性があります。それらが物事をスピードアップする場合、それは偶然である可能性があります。なぜなら、制約のないバージョンに適用されたときにコンパイラのヒューリスティックが事実上正しくなかったからです。
ラベルを変数に格納して変数に移動できる計算されたgoto(GNU拡張機能)の場合、効果はより顕著になる可能性があります。その場合、すべての可能なターゲットは、すべての可能なソースとレジスタ状態を共有する必要があります。
(通常)パフォーマンスに違いをもたらさないのは、ブロックの開始または終了とgoto
同等のbreak
またはcontinue
またはelse
です。オプティマイザーでも同じです。コンパイラーは、コードをいわゆる「基本ブロック」に分割し、それらの間にジャンプと条件付きジャンプを行います。通常、ジャンプの理由がであるかどうかは関係ありません。また、どちらのgoto
場合でも、レジスタの状態を正しく取得する必要があります。これが、ほとんどすべてのプログラミング構造が、発行された命令についてのみ考えている人によって「変装したgoto」として説明できる理由です。
[*]より正確に言うと、gotoで暗黙のザップが発生する可能性があります。つまり、一部のレジスタはソースで1つの目的に使用され、ターゲットではまったく使用されません。ただし、ターゲットが特定の値(変数の現在の値など)を含むことを期待し、ソースが含まないレジスタを作成することはできません。したがって、以前の場合、gotoを追加する場合は、ターゲットがそれを期待するのをやめるか、ソースがそこに配置する必要があります。通常、どちらもレジスタとスタック間で値をシャッフルするために追加のコードが必要になります。
プロのプログラミングの重要な機能である優れた構造と可読性のためだけに、パフォーマンスに影響を与えません。ただし、ループが深すぎる場合に goto を使用すると複雑さが緩和されることがありますが、特定の条件がトリガーされたときにジャンプしたい場合があります。それでも、他の方法で回避することもできます。