1

我有一个这样的嵌套if代码

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

现在显然,已经在 external 上检查了条件(1,2 和 3)if,所以我不希望在内部if-elsif语句中再次检查它们。所以我的解决方案是,完全移除外部if。但这又将使它通过if-elsif

那么如果有 10-15 个条件呢?哪一个更好?或者还有其他更好的解决方案吗?

4

6 回答 6

3

外部if是不必要的。

除此之外,只有三种可能的优化似乎是合理的:

  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 版本开始,有一个给定的/when 控制流

 use feature "switch";
于 2013-03-02T07:31:24.743 回答
0
  1. 删除外部if语句,因为内部语句无论如何都会检查所有条件if

  2. 如果你if按照条件1比条件2更重要的优先级来安排哪些条件,那么当然,你不能改变检查的顺序。

  3. 如果您if根据发生频率安排哪些条件,那么您可以在测试或分析程序时根据频率重新安排。

  4. 如果条件 1 为真,则运行语句 1。如果你的语句太长,那就把它们放到子程序中调用,这样看起来会更整洁。

    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 回答