如果循环内外的陈述?

Tim*_*mmy 11 optimization perl

如果我这样做会更好:

foreach my $item ( @array ) {
   if ( $bool ) {
     .. code ..
   }
   else {
     .. code ..
   }
}
Run Code Online (Sandbox Code Playgroud)

要么

if ( $bool ) {
   foreach my $item ( @array ) {
   }
}
else {
   foreach my $item ( @array ) {
   }
}
Run Code Online (Sandbox Code Playgroud)

Ken*_*ina 18

我会把过早的优化放在一边.

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

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

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

Barry Boehm报告说,20%的程序例程占用了80%的执行时间.在他的经典论文"对Fortran程序的实证研究"中,Donald Knuth发现,不到4%的程序通常占其运行时间的50%以上.

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

在初始开发期间专注于优化会减少实现其他计划目标.开发人员沉浸在算法分析和神秘的辩论中,这些辩论最终对用户没有多大价值.正确性,信息隐藏和可读性等问题成为次要目标,即使性能比其他问题更容易改进.事后性能工作通常只占程序代码的不到5%.您是否愿意返回并以百分之五的代码或可读性工作执行性能工作?

我并不是说不优化,而是最终只有优化代码,当你拥有大图片的奢侈品和工具指向正确的方向时.

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%
Run Code Online (Sandbox Code Playgroud)

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

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

在这里查看另一个问题.而从代码完成的第一个版本.

  • 我不知道在编写代码时考虑性能影响是否总是过早优化.我同意在这种情况下它可能是微不足道的,但我并不总是同意"过早优化"的一揽子声明. (7认同)
  • @Andy:嗯,在选择正确的算法等方面,那么是的,你必须知道选择哪些算法,这样你才不会认真地认真对待你的程序.但一般来说,在以最清晰的方式编写程序之后(可能会进行可能消除任何过早优化的重构),您的分析器会很好地告诉您当时需要修复的内容. (4认同)
  • 思考很好.考虑表现很好.但是如果你的编译器没有为语义相同的结构生成相同的代码,那么就该修复你的编译器了.不要对应用程序进行微优化以解决语言实现错误,这些错误在抽象的错误级别上运行. (4认同)

Lar*_*y K 7

第二个将更快,因为更少的比较. - 比较是在循环之外而不是在内部.

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

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


Gre*_*att 5

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


bri*_*foy 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 { ... } }
Run Code Online (Sandbox Code Playgroud)

这可能会在性能上失去一点点,但它更容易看,因为它不那么纠结的代码.在foreach没有关于分支或如何做出自己的决定在乎什么.当你想拥有更多分支时,这很有效.只要出现正确的内容$sub_ref,就不会更改迭代代码.