2

我只是在做一些快速的性能测试,我注意到一般初始化列表比显式初始化慢大约四到六倍(这些可能是错误的术语,我不确定这里的术语)。例如:

>>> import timeit
>>> print timeit.timeit('l = list()', number = 10000000)
1.66420578957
>>> print timeit.timeit('l = []',     number = 10000000)
0.448561906815

与元组和整数类似:

>>> print timeit.timeit('l = tuple()', number = 10000000)
1.10791182518
>>> print timeit.timeit('l = ()',      number = 10000000)
0.23167181015

>>> print timeit.timeit('l = int()', number = 10000000)
1.3009660244
>>> print timeit.timeit('l = 0',     number = 10000000)
0.232784032822

为什么是这样?

4

3 回答 3

8

使用dis 模块检查字节码:

import dis        
dis.dis(lambda: list())

产量

  6           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE        

尽管

dis.dis(lambda: [])

产量

  7           0 BUILD_LIST               0
              3 RETURN_VALUE        

因此list()需要查找全局名称并调用对象,[]而不需要。

于 2012-12-21T13:45:16.033 回答
2

这是因为使用文字语法,python 知道用一个字节码构建列表。调用构造函数需要查找list全局并改为调用它:

>>> def foo(): []
... 
>>> dis.dis(foo)
  1           0 BUILD_LIST               0
              3 POP_TOP             
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE        
>>> def bar(): list()
... 
>>> dis.dis(bar)
  1           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 POP_TOP             
              7 LOAD_CONST               0 (None)
             10 RETURN_VALUE        
于 2012-12-21T13:44:44.690 回答
2

不同的字节码。以list()vs[]为例:

l = list():
  1           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (l)

l = []:
  1           0 BUILD_LIST               0
              3 STORE_FAST               0 (l)

前者涉及名称查找"list"和函数调用。

于 2012-12-21T13:45:48.967 回答