gpt4 book ai didi

python - 算术表达式的优化 - 这种技术叫什么?

转载 作者:太空狗 更新时间:2023-10-29 17:17:11 27 4
gpt4 key购买 nike

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

>>> 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

第二个示例通过减少指令数量显然更有效。

我的问题是,这种优化是否有名称,为什么第一个示例中没有出现?

此外,我不确定这是否与 Why doesn't GCC optimize a*a*a*a*a*a to (a*a*a)*(a*a*a)? 重复;如果是,请进一步解释一下,因为它适用于 Python。

最佳答案

这种优化技术称为 constant folding .

常量折叠发生在后一种代码中而不是前一种代码中的原因是 Python 具有动态类型,而在数学中实数的乘积是可交换的和自由结合,在 Python 中一般情况下并非如此,因为既不是所有变量都包含实数,也不能事先知道类型。


Python 中的乘法是 left-associative - 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__ 定义为返回操作数的总和而不是乘积:

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) 中是错误的。

关于python - 算术表达式的优化 - 这种技术叫什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37179184/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com