是否在Python中缓存了常量计算?

时间:2015-10-07 19:09:06

标签: python

假设我在Python中有一个使用常量计算浮点值的函数,如1/3。

def div_by_3(x):
    return x * (1/3)

如果我重复调用该函数,是否会自动缓存1/3的值以提高效率?或者我是否必须手动执行以下操作?

def div_by_3(x, _ONE_THIRD=1/3):
    return x * _ONE_THIRD

1 个答案:

答案 0 :(得分:13)

了解自己! dis模块非常适合检查这类内容:

>>> from dis import dis
>>> def div_by_3(x):
...     return x * (1/3.)
... 
>>> dis(div_by_3)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (1)
              6 LOAD_CONST               2 (3.0)
              9 BINARY_DIVIDE       
             10 BINARY_MULTIPLY     
             11 RETURN_VALUE        

如您所见,1/3计算每次都会发生。 (注意:我将3更改为3.以强制浮动除法,否则它只是0.您还可以启用future-division,它实际上改变了行为,请参阅下面的编辑部分) 。

你的第二种方法:

>>> def db3(x, _ONE_THIRD=1/3.):
...   return x * _ONE_THIRD
... 
>>> dis(db3)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (_ONE_THIRD)
              6 BINARY_MULTIPLY     
              7 RETURN_VALUE        

有关第二个的更多信息可以通过inspect函数对象找到:

>>> inspect.getargspec(db3)
ArgSpec(args=['x', '_ONE_THIRD'], varargs=None, keywords=None, defaults=(0.3333333333333333,))

您可以看到默认值缓存在那里。

编辑:事实证明这更有趣 - 在Python 3中它们会被缓存(当你启用from __future__ import division时也会在Python 2.7中):

>>> dis.dis(div_by_3)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               3 (0.3333333333333333)
              6 BINARY_MULTIPLY
              7 RETURN_VALUE

在Python 3或2.7-with-future-division中切换到整数除法(//)并不会改变这一点,它只是将常量改为0而不是{ {1}}此外,直接在2.7 中使用整数除法而不使用 future-division也会缓存0.333..

今天学到了新东西!