如果循环内外的陈述?

时间:2010-02-11 04:18:09

标签: perl optimization

如果我这样做会更好:

foreach my $item ( @array ) {
   if ( $bool ) {
     .. code ..
   }
   else {
     .. code ..
   }
}

if ( $bool ) {
   foreach my $item ( @array ) {
   }
}
else {
   foreach my $item ( @array ) {
   }
}

6 个答案:

答案 0 :(得分:18)

我会将premature optimization放在一边。

  

“过早优化是所有邪恶的根源” - 唐纳德克努特

你应该首先考虑可维护性。考虑到代码的逻辑结构(例如将相关语句分组在一起),以更有意义的方式对它们进行分组。

如果您稍后确定性能是一个问题,请尝试使用类似于分析器的测量来查看瓶颈所在。机会是,它不存在。从代码完成2:

  Barry Boehm报道了20%的人   一个程序的例程消耗80   执行时间的百分比。在他的   经典论文“对中国的实证研究”   Fortran计划,“唐纳德克努特发现   不到百分之四的   程序通常占比超过   50%的运行时间。

我们不应该在必要之前猜测在哪里进行优化,因为我们大多数人都非常不愿意猜测代码的缓慢部分在哪里。随时优化的程序员也花费大约96%的时间来优化不需要优化的代码。另一件需要考虑的事情是代码调优(如本例所示)考虑了可读性和性能可维护性之间的权衡:

  

专注于优化   初步发展有弊   实现其他计划目标。   开发人员沉浸其中   算法分析和神秘的辩论   这最终没有多大贡献   给用户的价值。关注的问题   正确性,信息隐藏和   可读性成为次要目标,   即使性能更容易   比其他人提高   关注的是。事后表现   工作通常影响不到五个   程序代码的百分比。你会   而是回去做表演工作   百分之五的代码或   可读性100%工作?

我不是说不优化,而是仅在最后优化代码,当你拥有大图片的奢侈品和指向你的工具时正确的方向。

EXTRA:尽管如此,要回答性能问题:

  

这个[“不开启”的代码]可节省大约20%的时间:

Language        Straight Time    Code-Tuned Time    Time Savings
C++             2.81             2.27               19%     
Java            3.97             3.12               21%
Visual Basic    2.78             2.77               <1%
Python          8.14             5.87               28%
  

与此情况不同的危险是两个环必须平行保持。   [...]你必须记住在两个地方改变代码,这是一个烦恼   对于那些必须使用代码的人来说,这是一个令人头疼的问题。

     

此示例还说明了代码调优中的一个关键挑战:任何特定的影响   代码调优是不可预测的。代码调优产生了显着的改进   四种语言中的三种,但不是在Visual Basic中。执行此具体   在这个特定版本的Visual Basic中进行优化会产生较少的可维护性   代码没有任何抵消性能增益。一般的教训是你必须   测量每个特定优化的效果,以确保其效果 - 没有   例外。

在此处查看this other问题。并且第一版Code Complete中的this

答案 1 :(得分:7)

由于更少的比较,第二个会更快。 - 比较是在循环之外而不是在内部。

由于比较变量是一个循环不变量,如果它不是更清晰的编码,我会感到惊讶。

实际速度差(挂钟时间)取决于阵列的大小

答案 2 :(得分:5)

如果你正在优化速度,那么第二个(if分支中的foreach循环)应该更快,因为你不会在每个循环迭代中进行测试。

答案 3 :(得分:5)

每个人似乎都陷入了性能问题。

永远不必重复代码几乎总是更好。也就是说,不止一次输入相同的东西应该是痛苦的。既然你没有说过每个代码,我会假设你想在每种情况下做不同的事情。我倾向于将迭代的细节与特定处理分开。

 my $sub_ref = $bool ? make_true_function() : make_false_function();

 foreach my $element ( @array ) {
      $sub_ref->( $element );
      }

 sub make_true_function  { sub { ... } }
 sub make_false_function { sub { ... } }

这可能会在性能上失去一点点,但它更易于查看,因为它不那么纠结的代码。 foreach并不关心分支或您如何做出决定。当你想拥有更多分支时,这很有效。只要在$sub_ref中显示正确的内容,就不会更改迭代代码。

答案 4 :(得分:3)

我建议你们两个时间,亲眼看看,但我不认为差别很大。

答案 5 :(得分:2)

简单地评估一下你在这里做的布尔变量,它们大致相同。但是,如果变量被一个需要很长时间来评估的复杂表达式替换,那么第二个例子会更好,因为它只会被评估一次。