web-dev-qa-db-ja.com

ネストされた条件文はパフォーマンスに大きな影響を与えますか?

これは長い間私の心の中にある質問です。

複数のネストされた条件ステートメントを使用すると、取得したコードのパフォーマンスに影響がありますか?これまでのところ、プログラマーがこの状況を説明するための正確な用語、有名な「破滅のピラミッド」 [Wikipedia page] を作成したことを知っていますが、どのくらいこれはパフォーマンスを低下させますか?

例としてこの状況を考えてみましょう。アプリケーションでのユーザーの購入を表すいくつかのオブジェクトを含むサーバー応答からのJSONがあり、そこから必要なデータを取得する前に、さまざまな条件を確認する必要があります。

  1. 私たちが探している反応はありますか?
  2. 応答にresultCode: OKがありますか?
  3. 処理する内容はありますか?

この時点ですべてがtrueである場合、「処理プロセス」が開始され、サーバー応答の解析と編集が行われます。この場合、日付形式が米国から標準のヨーロッパ形式に変更されます。プロセスは、2つのネストされたfor-loopsとif statementで構成されます。

私はiOS開発者なので、これはObjective-Cのサンプルコードです。

if ([remoteManager.operationId isEqualToString:NEEDED_OPERATION_ID]) {
    if ([response[RESULT_CODE_KEY] isEqualToString:@"OK"]) {
        if ([response[RESULT_OBJ_KEY][@"CONTENT_LIST"] count] > 0) {
            NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];

            for (NSMutableDictionary *productsAvailable in response[RESULT_OBJ_KEY][@"CONTENT_LIST"]) {
                for (NSString *key in productsAvailable) {
                    if ([key isEqualToString:@"NEEDED_KEY"]) {
                        /* We change the date format here */
                    }
                }
            }
        }
    }
}

私の意見では、これらのチェックはシステムが行うのにそれほど複雑ではないので、このコードは実際にはアプリケーションのパフォーマンスに影響を与えることはできません。しかし、最大の速度とパフォーマンスが必要な場合、これは問題になる可能性がありますか?言い換えると、ネストされた条件文を回避する必要があるかどうか。また、同時に複数の条件を設定すると、パフォーマンスの問題(ある場合)が減少しますか?

3
Aluminum

説明した一連のステップは、アプリケーションが達成すべきことを達成するために、必須の一連のステップであるように見えます。したがって、追加または削除できるものはありません。

既存のコードでは、次のオプションがあります。

  • 条件が評価される順序を並べ替えます。おそらく、最も頻繁に失敗する条件が最初に評価されるように条件を再配置するか、計算量の多い条件を並べ替えることにより、パフォーマンスを向上させることができます。は最後に評価されますが、努力する価値はほとんどありません。いずれにしても、試行する前に何かを測定するのに時間を費やす必要があります。

  • 入れ子をANDで結合した複数の式で置き換えます。 Objective-Cについては何も知りませんが、Cの伝統に忠実であり、ブール式の短絡評価を使用することを望んでいます。したがって、コンストラクトif(a) { if(b) { ... } }if((a) && (b)) { ... }と同等であるため、ネストしてもネストしなくてもまったく違いはありません。

  • 入れ子を早期終了に置き換えます。早期終了とは、if(!a) return; if(!b) return; bulk-of-code-goes-here.と言うときです。ネストを減らすために早期終了を主張する人と、問題がないと考える人がいます。入れ子にし、早期終了は悪だと信じています。ただし、これでもコードの実行速度に違いはないため、この問題はパフォーマンスではなくスタイルに関するものです。「ネストするかしないか」は主観的な質問であり、主観的な回答しか得られません。 (もちろん、これは "die、you nesting fool!"

したがって、物事を改善するためにできることはほとんどありません。入れ子にしても入れなくても、パフォーマンスにはまったく影響しません。その上、条件をどのように構造化しても、コンパイラーは通常、同じ結果が得られる限り、適切と思われる方法でマシンコードを自由に出力できるため、ネストされた条件はおそらく早期終了として実装されます。コンパイラによる、短絡評価と同じように。つまり、1日の終わりに、条件文を配置する方法の唯一の基準はそれらを読んで理解することが最も自然な方法であることです

あなたの質問が実際にマイクロ最適化に関する別の質問の重複であるというgnatの優れた(そして皮肉な)提案に含まれるアドバイスに注意することをお勧めします:コードのパフォーマンスについて心配するのをやめますあなた最終製品で実際にパフォーマンスが低下していることが判明した場合にのみ、パフォーマンスが心配されるようになります。それでも、発見される解決策は、アルゴリズムによる大規模な最適化である可能性が高くなります。 そして、彼らがあなたが個々の指示を注文する方法と関係があることはほとんどありません。

7
Mike Nakis

ネストされた条件の問題はスピードではなく、人間の理解です。

人間は一度に多くの可能性に対処するのに苦労しています。彼らは限界(かなり小さい)に達し、それを認識せずに間違いを始めます。

2、4、8、16、32、64、128 ...などの条件付きステートメントは、かなり迅速に複雑さを増します。ほとんどすべてのプログラマーにとって、制限は1桁です。

コンピュータは、非常に多くのネストされた条件でコードを最適化するのに問題はありませんが、人間はソースコードを維持することがほとんど不可能であることを認識します。つまり、機能しません。

ほとんどのプログラミング手法は、速度ではなく人間の弱点に対処することを目的としています。ソースコードは人間用です。

8
user147272