有没有短路乘法之类的东西?
Posted
技术标签:
【中文标题】有没有短路乘法之类的东西?【英文标题】:Is there such a thing as short circuit multiplication? 【发布时间】:2011-12-30 01:27:47 【问题描述】:我们都知道逻辑表达式中的短路,即当
if ( False AND myFunc(a) ) then
...
不必费心执行myFunc()
,因为if
条件不可能为真。
我很好奇你的日常代数方程是否有等价物,比如说
result = C*x/y + z
如果C=0
没有必要评估第一项。如果x
和y
是标量,那么在性能方面并没有多大关系,但是如果我们假装它们是大矩阵并且操作代价高昂(并且适用于矩阵),那么它肯定会有所作为。当然,您可以通过添加if C!=0
声明来避免这种极端情况。
所以我的问题是这样的功能是否存在,是否有用。我不是一个程序员,所以它可能以我没有遇到过的名字命名;如果是的话请赐教:)
【问题讨论】:
从功能的角度来看,逻辑短路是一个重要的概念,而“算术短路”只是编译器级别的优化,没有功能差异。您选择的语言可能已经在您不注意的情况下在幕后进行。 比我了解更多的人应该回答,但我想如果你把这个部门短路了,你会遇到问题。例如,如果 y=0,会发生什么?如果短路,当答案实际上是错误时,它将返回 0。 @deceze 算术短路确实具有超出优化的功能差异,就像逻辑短路一样。考虑result = C*myfunction()
。如果C==0
导致算术表达式短路,则永远不会调用myfunction
,并且不会发生它可能产生的任何副作用(就像逻辑短路一样)。
理论上,如果您将一系列值相乘并遇到 0;你可以停在那里。我是否/真正的编译器如何实现这种优化。正如@Maxy-B 提到的,编译器必须确保没有副作用。
【参考方案1】:
您所说的概念有不同的名称:惰性评估、非严格评估、按需调用,命名为很少,实际上比在这里和那里避免乘法要强大得多。
像Haskell 或Frege 这样的编程语言的评估模型是非严格的。在那里编写您的“短路”乘法运算符将非常容易,例如您可以编写如下内容:
infixl 7 `*?` -- tell compiler that ?* is a left associative infix operator
-- with precedence 7 (like the normal *)
0 *? x = 0 -- do not evaluate x
y *? x = y * x -- fall back to standard multiplication
【讨论】:
谢谢!接受回答一些后续问题。【参考方案2】:如果数据很大和/或复杂并且操作代价高昂,那么操作的实现应该在执行代价高昂的操作之前执行适当的快捷方式检查。它是运算符(例如,矩阵 *)实现的内部细节,但实际上与“乘法”的语言概念无关,并且对您编写计算的方式影响不大。
【讨论】:
以上是关于有没有短路乘法之类的东西?的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑矩阵乘法+Floyd