短路是不是使程序的执行更快,并且分析在条件语句中首先放置的语句是不是值得? [关闭]

Posted

技术标签:

【中文标题】短路是不是使程序的执行更快,并且分析在条件语句中首先放置的语句是不是值得? [关闭]【英文标题】:Does short circuiting make execution of the program faster, and is analysing which statement to put first in the condition statement worth it? [closed]短路是否使程序的执行更快,并且分析在条件语句中首先放置的语句是否值得? [关闭] 【发布时间】:2016-11-26 16:40:24 【问题描述】:

例如(假设我们正在谈论 C++,如果这会有所不同), 在 && 运算符中,如果我知道一个语句会更频繁地产生 0/有更高的机会,那么我应该将另一个语句放在左侧,而将另一个语句放在右侧?

|| 也是如此运算符,如果我知道一个语句会更频繁地产生 1/有更高的机会,那么另一个语句应该放在左侧,而另一个语句放在右侧?

现在做这一切会花费大量时间来分析程序,但如果这确实加快了程序的执行时间,是否值得这样做,嵌入式/实时系统程序员是否考虑加速必要时提交申请?

【问题讨论】:

值得这样做将取决于很多因素。最大的问题是进行此调整需要多少成本,以及您从增加的性能中节省了多少。 原则上是的,这就是短路算子存在的原因 首先确保程序正确。然后,如果它太慢,请对其进行分析。修复任何减慢它的东西。不要在分析之前浪费时间。这是我的意见;以主要基于意见投票结束。 @OmidCompSCI:通常最快的解决方案通常是简单而优雅的(在源代码级别),因此这些语句通常自然地以最佳顺序结束。否则,您可能正在处理必须来自探查器的硬数据的事情。如果不使用当今复杂的机器进行测量,就没有优化的捷径,太多的善意很容易适得其反。 我有一个案例,其中几个昂贵的计算条件在一个非常便宜的条件之前被检查,这会在 90% 的时间里拒绝整个事情。重新排序是一个巨大的胜利,但也是一个非常特殊的情况。 【参考方案1】:

这取决于。 如果语句很简单:

if(y == 4 || x == 2)

并假设 x == 2 的频率要高得多,因此我们可以通过编写如下代码来短路执行:

if(x == 2 || y == 4)

但是你看我们不会从中得到太多好处,因为语句非常简单,在这个级别优化代码可能不那么值得。

现在考虑一个类似的例子:

if(y == an_expensive_function() || x == 2)

这里假设 an_expensive_function() 是非常昂贵的操作,说它的复杂性是指数级的,绝对可以这样写:

if(x == 2 || y == an_expensive_function())

进行短路。

嵌入式和应用程序开发人员或任何开发人员最初可能不会考虑以如此精细的粒度进行优化,如果这不会给他们带来太多好处的话。如果事情对他们来说很好,他们甚至可能不会考虑。 所以作为一个开发者,我们需要检查一下,在这样一个级别上分析和优化代码需要多少时间,我们从中获得了多少收益。

【讨论】:

感谢您的解释,以及理解的好例子!显然每个人都在说,没有人真正将代码微调到这种极端,在进入这些细节之前,首先解决瓶颈很重要。【参考方案2】:

首先,确保您不是过早优化的受害者。

话虽如此,请确保您已尽一切努力加快程序的瓶颈


在某些情况下,按照您所说的短路可能是个好主意,但这在很大程度上取决于您的所有陈述。

例如,如果你有类似的东西:

if(slowFunction() && complexConditionRootsAndExponents && ConditionUsuallyZero)

那么您可能希望最后一个学期排在第一位,不是吗?

但是,请注意,按逻辑顺序排列的事情并不总是微不足道的。以我在Why this program printed fork 4 times? 中的回答为例,可以看到短路会影响程序的执行流程。


TL;DR

不过,一般来说,通过改变条件中的条款来获得显着加速是很少见的。 关注程序的瓶颈并尽可能努力地解决它!

【讨论】:

感谢您的示例和参考。是的,我不知道过早的优化是一回事,但是我现在明白了,应该首先解决瓶颈! 欢迎您@OmidCompSCI。你问了一个很好的问题,几年前我也问过这个问题,我犯了一个错误来尝试优化这个,而不是瓶颈。这并没有什么不同。但是优化程序的瓶颈肯定会带来不错的结果! :) 祝你好运。【参考方案3】:

问题的答案是:是的,它确实会影响性能。

性能提升是否值得为找到可以改进的位置和更改程序而付出代价,这只有您可以回答。

在大多数情况下,性能变化会很小,但如果所涉及的某些操作代价高昂,则可能会很重要。

请注意,也可能存在正确性影响。例如,如果在 if (foo() || bar()) 中,如果 foo 返回 true,则永远不会调用 bar 很重要,那么重新排序调用将是一个错误。

首先确保您的程序正确。那么,if 太慢了;分析它并优化它将产生最大影响的地方。这可能是短路上下文中的评估顺序,但在大多数情况下它会是别的东西。

【讨论】:

谢谢,看来找到瓶颈比寻找这些小东西更重要,因为在大多数情况下,成本似乎比找到这些情况要大。【参考方案4】:

您还必须考虑,每一方的评估成本有多大。

if (veryCostlyOftenFalse() && veryCheapRareFalse()) // may be faster other way around

除非超过 50% 的来源是表达式评估和分支,否则我会说这是最后的优化,当您对其他一切感到满意时。


嵌入式/实时应用程序程序员大致按以下顺序关注:

    当然是算法,在速度与空间之间找到合理的权衡。 内存中的数据结构(在使用这些算法时,尽可能频繁地访问缓存)。 使用真实数据分析真实应用程序,看看是否存在一些意想不到的瓶颈并解决这些问题。 如果您在某个地方极度想念一两个时钟,并且周围有一些复杂的if,那么是的,它可能会有所帮助...

【讨论】:

感谢您告诉我嵌入式/实时程序员关注什么。【参考方案5】:

当然。如果您的条件是以下形式:

if ( x() && y() ) ...

y 的计算成本很高,而 x 很便宜并且经常失败, 这将提高代码的本地性能。

所以你想知道:

是程序性能敏感部分中的条件(如果不是,则没有优化它的意义,为清楚起见编写) 短路表达式的组件计算的相对成本 哪些廉价计算经常失败(对于 &&)或成功(对于 ||)。

在这种情况下,通常值得重新排列短路表达式元素。

【讨论】:

感谢您提供简短的示例和解释。似乎大多数人都说在这样的简单场景中最好重新排列它们以提高性能,在复杂的情况下,分析它的成本将远大于性能,如果有任何改进的话。看来关键是要解决性能下降的瓶颈!谢谢。 FWIW,当我写这样的条件时,我会尝试根据我所知道的来判断我写它时的顺序。有些人可能称之为过早优化;我不觉得贬义是应得的。如果条件很少执行,那么我的顺序是否错误也没关系。如果条件意外地出现在热门路径中,那么在我估计正确的程度上,排序已经正确,我不必使用分析器找到这个地方并稍后修复它;我的代码已经调整好了。如果我到处都这样做,我的代码通常会运行得更好。

以上是关于短路是不是使程序的执行更快,并且分析在条件语句中首先放置的语句是不是值得? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

where条件放在子SQL语句中是否查询速度更快?

如何使复杂的条件看起来不错并节省语句的数量?

python条件判断

Python2.7条件与循环

Python3.7条件与循环

js的if判断问题