optimization - 为什么大多数语言不能优化 “0 * …”,并且有任何语言可以优化?

标签 optimization syntax language-agnostic

我正在编写一个2D曲线算法,并且有一些代码可以对la进行求和:

for (i=0, end=...; i<end; i++) {
  value += coefficients[i] * expensiveToCalculateValue(i);
}

其中某些迭代步骤的coefficients[i]值为零。由于零乘以某种东西仍然为零(至少在简单的算术规则下),因此我认为可以通过首先检查coefficients[i]是否为零,并且如果是这样,仅continue进行下一次迭代,就可以显着优化此代码。添加,排序,效果很好。

但这留下了一个问题:为什么不为我做这件事?这不是乘法的某些创意小众版本,它是简单的算术运算。几乎所有语言都会短路二进制的OR和AND运算(如果找到了一个操作数),该运算数从那时起将使结果不变,那么为什么算术乘以零不会同样短路呢?

我尝试在Java,PHP,JavaScript,Perl,Python,C++中运行此代码(针对synax进行了修改),甚至还看过Prolog的功能,但是他们都没有意识到,一旦看到“零次……”,他们不必评估可能昂贵的第二(或第三,第四等)条件:
printed = 0;
function veryExpensive() {
  print "oh god this costs so much, x" + (printed++);
  return 0;
}
value = 0 * veryExpensive() * veryExpensive() * veryExpensive()

所有这些最终都只运行了veryExpensive() 3次。

现在,我知道您可以-如果您是这种人-可以根据自己的执行情况写veryExpensive函数来执行管理性开销工作,尽管它的结果对算术表达式没有贡献(如果您这样做,这样做,您可能正在滥用一种语言,但是每个人在编程生命中的某个时候都喜欢偷偷摸摸的忍者代码),但是您这样做只是因为您知道该语言恰好没有针对这种情况进行优化。如果语言为您优化了算术评估,那么您的代码表达能力就不会受到任何阻碍。

因此:是否有一些历史先例导致大量当前使用的语言针对“true OR ...”和“false AND ...”而不是“零时间...”进行优化?为什么我们针对二进制运算而不是MUL 0进行优化? (如果幸运的话,会有一个有趣的故事来讲述为什么我们现在不短路)

更新

John Skeet和Nik Bougalis都提出了很好的论据,说明了为什么以一种现成的语言进行优化会导致问题,但是Nik的答案与这个问题更加吻合,因此我将他的答案标记为“正确”的答案。也就是说,它们涵盖了同一问题的不同方面,因此真正的答案是两者的结合。

最佳答案

让编译器自动添加运行时检查可能有意义,也可能没有意义。在您的特定情况下,检查确实可以提高性能,但您的特定情况并不是判断优化的最终结果。

如果乘法非常昂贵,并且微处理器没有对乘法进行内部零优化,并且可以确保乘法的结果为零(例如0 * NaN != 0)为零,那么检查可能很有意义。但这是很多操作数,并且您知道,您可以将and短路。

假设您具有数字的准随机分布,并且具有零与非零数字的未知比例。根据比率,零和非零序列的运行长度以及处理器的分支预测算法,检查实际上可能会引起麻烦(即管道停顿)。

您是否仍然认为编译器应该代表您插入这样的检查?

关于optimization - 为什么大多数语言不能优化 “0 * …”,并且有任何语言可以优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15278064/

相关文章:

language-agnostic - IF-ELSE和SWITCH有什么区别?

java - 对此 for 循环语法感到困惑

javascript - 如何停止渲染阻塞 Javascript 和 CSS?

MySQL 是否可以在 LIMIT 语法之后进行子查询?如果不是,为什么?

c++ - 加减一组数字以达到一个值

java - 静态错误 : This class does not have a static void main method accepting String[]

python - NoneType 没有属性 Append

algorithm - 针对多种模式进行高效字符串匹配的数据结构

python - 优化零重力二维空间中粒子的重力计算

c++ - 如果使用优化 (-O2, -O3),为什么这段代码的行为会有所不同?