Python中全局名称的本地重新绑定如何使代码更快/更优化?

时间:2014-08-28 13:50:53

标签: python

我正在阅读关于Effbot的Default Parameter Values in Python

本文后面有一节介绍作者谈论Valid uses for mutable defaults并引用以下示例:

and, for highly optimized code, local rebinding of global names:

import math

def this_one_must_be_fast(x, sin=math.sin, cos=math.cos):
    ...

我无法确定这是如何导致快速/高度优化的代码执行的。有人可以通过充分了解(最好是引用)答案来启发这个问题吗?

1 个答案:

答案 0 :(得分:4)

CPython对本地变量的访问是基于 index 的(涉及LOAD_FAST操作码)。

另一方面,通过字典中的名称查找访问全局变量(使用操作码LOAD_GLOBAL)。对于模块变量,它是一个两步过程。使用第一个查找(LOAD_GLOBAL)来推送模块对象,然后使用第二个查找(LOAD_ATTR)来找到适当的成员。

即使字典查找得到高度优化,也无法实现间接访问。

import math
def f():
    math.sin(1)

  4           0 LOAD_GLOBAL              0 (math)   ***
              3 LOAD_ATTR                1 (sin)    ***
              6 LOAD_CONST               1 (1)
              9 CALL_FUNCTION            1
             12 POP_TOP             
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE


from math import sin
def f():
    sin(1)

  4           0 LOAD_GLOBAL              0 (sin)    ***
              3 LOAD_CONST               1 (1)
              6 CALL_FUNCTION            1
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE


def f(sin=math.sin):
    sin(1)


  7           0 LOAD_FAST                0 (sin)    ***
              3 LOAD_CONST               1 (1)      
              6 CALL_FUNCTION            1
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE