1

このようなネストされたifコードがあります

 if (condition1 or condition2 or condition3 ) {
           if  (condition1) {
           }
           elsif (condition2) {
           }
           elsif (condition3) {
           }
 }

明らかに、条件(1、2、および3)はすでにouterでチェックされているため、innerステートメントifでそれらを再度チェックしたくありません。if-elsifだから私の解決策は、外側をif完全に取り除くことでした。しかし、これでもif-elsif.

では、条件が 10 ~ 15 個ある場合はどうなるでしょうか。どちらの方がよいですか?または、他のより良い解決策はありますか?

4

6 に答える 6

3

アウターifは不要です。

それに加えて、3つの可能な最適化だけが合理的であるように思われます。

  1. 最適化する前にコードをプロファイリングし、最も一般的な条件が最初にテストされるようにif/else条件を並べ替えます。
  2. データ構造を使用して条件を表します。ある種の等式(if ($foo eq $bar){...}elsif($foo eq $baz){...})をテストする場合、ハッシュはルックアップを線形時間から定数時間に変換できます。

    %hash = ($bar => sub{...}, $baz => sub{...});
    my $code = $hash{$foo} or do{"this is the trailing else"};
    $code->(); # execute the coderef
    

    これは非常に柔軟ですが、クロージャの間接参照が含まれます。

  3. 条件を再確認する必要がある場合は、結果をキャッシュします。条件で宣言された変数のスコープは、後続のすべての条件とif/elseチェーンのブロックに到達します。

    if ( my $cond1 = ... and ...) {
      ...
    } elsif ($cond1 and my $cond2 = ...) {
      ...
    } elsif ($cond2) {
      ...
    }
    
于 2013-03-02T07:25:57.150 に答える
2

コードが実行される頻度によって異なります。複雑なifステートメントのセットでは、他のほとんどの操作と比較して安価であるため、読みやすさを最適化することをお勧めします。ただし、上記の例では、外側のステートメントを完全に削除します。これは単に不要です。Perlは、とにかくコードを解析しながらコードを最適化します。

于 2013-03-02T07:25:03.420 に答える
2

条件がすべて同じ変数の値に対するテストである場合、Perl 5.10.1 以降ではgiven/を使用できます。when

use 5.010;

given ($foo) {
  when ('bar') { ... }                  # string literal
  when (4) { ... }                      # numeric literal
  when (qw[ xyzzy plugh ]) { ... }      # any of multiple literals
  when (/^whee+$/) { ... }              # regex match
  default { ... }                       # fallthrough if nothing matched
}
于 2013-03-02T10:50:48.857 に答える
1

おそらく、Switch 制御文はコード内で意味を持つ場合があります (チェックしている条件によって異なります)。Switchのドキュメントを見てください。

更新 5.10 perl リリースから、given/when 制御フローがあります。

 use feature "switch";
于 2013-03-02T07:31:24.743 に答える
0
  1. ifとにかくすべての条件が内部ステートメントによってチェックされるため、外部ステートメントを削除しますif

  2. 条件1のように優先度に従ってどのif条件を条件2よりも重要にするかを調整する場合、もちろん、チェックの順序を変更することはできません。

  3. 発生頻度に応じて条件をif調整すると、プログラムをテストまたはプロファイリングするときに、頻度に基づいて再配置できます。

  4. condition1がtrueの場合、statement1を実行します。ステートメントが長すぎる場合は、それらをサブルーチンに入れて呼び出すと、見栄えが良くなります。

    if    (condition1) {&run_statement1();}
    elsif (condition2) {&run_statement2();}
    elsif (condition3) {&run_statement3();}
    elsif (condition4) {&run_statement4();}
    elsif (condition5) {&run_statement5();}
    elsif (condition6) {&run_statement6();}
    elsif (condition7) {&run_statement7();}
    else               {&run_elsestatement();}
    
  5. コードを不必要に複雑にしたり、難読化したりしないでください。シンプルで読みやすく、目的を達成してください。

于 2013-03-02T08:09:26.840 に答える
0

またはこれ:

(condition1) ? run_statement1() :
(condition2) ? run_statement2() :
(condition3) ? run_statement3() : run_elsestatement() ;

私はタイピングが少ないのが好きです。評価された条件が「一意の」結果を生成する場合の別のオプションは、結果を関数のハッシュのキーとして使用することです。これにより、上記の条件付きチェックが完全に削除されます。

たとえば、条件が「$var」というスカラーに保持されている値に基づいている場合、これらの異なる値をハッシュのキーとして単純に使用できます。

$conditionalFunctionHash{$var}->();
于 2013-03-03T06:44:25.667 に答える