1. user 0m1.828s
    2. sys 0m0.012s

    然而不把它放在函数里:

    它比上一个运行时间更长

    1. real 0m4.543s
    2. user 0m4.524s

    为啥会这样?


    你或许想问为什么存取一个本地变量比全局变量要快.这有关于CPython的实现细节.

    记住CPython解析器运行的是被编译过的字节编码(bytecode).当一个函数被编译后,局部变量被存储在了固定大小的数组(不是一个dict),而变量名赋值给了索引.这就是为什么你不能动态的为一个函数添加局部变量.检查一个局部变量就好像是一个指针去查找列表,对于在PyObject上的引用计数的增长是微不足道的.

    相反的在查找全局变量(LOAD_GLOBAL)时,涉及到的是一个实实在在的dict的哈希查找.顺便说一句,这就是为什么当你想要一个全局变量你必须要在前面加上:如果你在一个区域内指定一个变量,编译器就会建立一个STORE_FAST的入口,除非你不让它那么做.


    在一个函数里,字节码是这样的:

    如果在全局,字节码:

    1. 1 0 SETUP_LOOP 20 (to 23)
    2. 3 LOAD_NAME 0 (xrange)
    3. 6 LOAD_CONST 3 (100000000)
    4. 9 CALL_FUNCTION 1
    5. 12 GET_ITER
    6. 16 STORE_NAME 1 (i)
    7. 2 19 JUMP_ABSOLUTE 13
    8. >> 22 POP_BLOCK
    9. >> 23 LOAD_CONST 2 (None)

    两者的区别是比STORE_NAME要快很多.这是因为在函数里i是一个局部变量而在全局区域它是一个全局变量.