这种技术叫什么?

与朋友的讨论导致了以下认识:

>>> import dis
>>> i = lambda n: n*24*60*60
>>> dis.dis(i)
  1           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (24)
              6 BINARY_MULTIPLY
              7 LOAD_CONST               2 (60)
             10 BINARY_MULTIPLY
             11 LOAD_CONST               2 (60)
             14 BINARY_MULTIPLY
             15 RETURN_VALUE
>>> k = lambda n: 24*60*60*n
>>> dis.dis(k)
  1           0 LOAD_CONST               4 (86400)
              3 LOAD_FAST                0 (n)
              6 BINARY_MULTIPLY
              7 RETURN_VALUE

第二个例子显然更简单,只需减少指令的数量。

我的问题是,是否有这个优化的名称,为什么它不会在第一个例子中发生?

另外,我不确定这是否是GCC为a * a * a * a(a * a * a)*(a * a * a)优化的重复内容。 ; 如果是这样,请进一步解释一下,因为它适用于Python。


这种优化技术被称为常量折叠。

在后面的代码中出现持续折叠的原因是Python没有动态类型,而在数学中,实数的乘积是可交换和自由关联的,但在一般情况下Python并不是这样,因为既不是做所有的变量都包含实数,也不能事先知道类型。


Python中的乘法是左联合的 - 24 * 60 * 60 * n行为类似于(((24 * 60) * 60) * n) ,它又隐式地执行

(24).__mul__(60).__mul__(60).__mul__(n)

要么

(n).__rmul_((24).__mul__(60).__mul__(60))

n * 24 * 60 * 60 ,其是(((n * 24) * 60) * 60)可以表现得像

n.__mul__(24).__mul__(60).__mul__(60)

要么

(24).__rmul__(n).__mul__(60).__mul__(60)

由于我们事先不能知道n.__mul__的行为,所以在后一种情况下我们不能折叠常数。 考虑这个有趣的类的例子,它返回一个int的子类,它将__mul__ / __rmul__定义为返回操作数的总和而不是product:

class MultiplyAsAdd(int):
    def __mul__(self, other):
        return MultiplyAsAdd(self + other)
    def __rmul__(self, other):
        return MultiplyAsAdd(other + self)

然后

>>> (lambda n: 24*60*60*n)(MultiplyAsAdd(5))
86405
>>> (lambda n: n*24*60*60)(MultiplyAsAdd(5))
149

很明显,在后一种情况下,Python将产品加括号为n*(24*60*60)是错误的。

链接地址: http://www.djcxy.com/p/15033.html

上一篇: what is this technique called?

下一篇: fast square root optimization?