user 0m1.828s
sys 0m0.012s
然而不把它放在函数里:
它比上一个运行时间更长
real 0m4.543s
user 0m4.524s
为啥会这样?
你或许想问为什么存取一个本地变量比全局变量要快.这有关于CPython的实现细节.
记住CPython解析器运行的是被编译过的字节编码(bytecode).当一个函数被编译后,局部变量被存储在了固定大小的数组(不是一个dict
),而变量名赋值给了索引.这就是为什么你不能动态的为一个函数添加局部变量.检查一个局部变量就好像是一个指针去查找列表,对于在PyObject
上的引用计数的增长是微不足道的.
相反的在查找全局变量(LOAD_GLOBAL
)时,涉及到的是一个实实在在的dict
的哈希查找.顺便说一句,这就是为什么当你想要一个全局变量你必须要在前面加上:如果你在一个区域内指定一个变量,编译器就会建立一个STORE_FAST
的入口,除非你不让它那么做.
在一个函数里,字节码是这样的:
如果在全局,字节码:
1 0 SETUP_LOOP 20 (to 23)
3 LOAD_NAME 0 (xrange)
6 LOAD_CONST 3 (100000000)
9 CALL_FUNCTION 1
12 GET_ITER
16 STORE_NAME 1 (i)
2 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 2 (None)
两者的区别是比STORE_NAME
要快很多.这是因为在函数里i
是一个局部变量而在全局区域它是一个全局变量.