def main(): for i in xrange(10**8): pass main()
这段 Python 中的代码运行在(注:计时是用 Linux 中 BASH 中的 time 函数完成的。)
real 0m1.841s user 0m1.828s sys 0m0.012s
但是,如果 for 循环没有放在函数中,
for i in xrange(10**8): pass
然后它运行更长的时间:
real 0m4.543s user 0m4.524s sys 0m0.012s
为什么是这样?
您可能会问 为什么 存储局部变量比存储全局变量更快。这是一个 CPython 实现细节。
请记住,CPython 被编译为解释器运行的字节码。编译函数时,局部变量存储在固定大小的数组( 不是 a dict)中,变量名称分配给索引。这是可能的,因为您不能动态地将局部变量添加到函数中。然后检索局部变量实际上是对列表的指针查找和引用计数的增加,PyObject这是微不足道的。
dict
PyObject
将此与全局查找 ( ) 进行对比,后者是涉及哈希等LOAD_GLOBAL的真正搜索。dict顺便说一句,这就是为什么您需要指定global i是否希望它是全局的:如果您曾经分配给范围内的变量,编译器将发出STORE_FASTs 访问它,除非您告诉它不要这样做。
LOAD_GLOBAL
global i
STORE_FAST
顺便说一句,全局查找仍然非常优化。属性查找foo.bar真的 很 慢!
foo.bar
这是关于局部变量效率的小插图。