在python中,为什么从数组中读取比从列表中读取要慢?

时间:2010-07-17 14:13:29

标签: python

我最近正在学习python,并且正在使用该语言进行许多练习。

我发现有趣的一点是,当我从数组中读取时,它几乎比列表慢一半的时间。有人知道为什么吗?

这是我的代码:

from timeit import Timer
import array

t = 10000
l = range(t)
a = array.array('i', l)
def LIST():
    for i in xrange(t):
        l[i]

def ARRAY():
    for i in xrange(t):
        a[i]

print Timer(LIST).timeit(1000);
print Timer(ARRAY).timeit(1000);

输出是:

0.813191890717
1.16269612312

表示读取数组比列表慢。 我认为数组是一个固定大小的内存,而list是一个动态结构。 所以我假设数组比列表更快。

有没有人有任何解释?

3 个答案:

答案 0 :(得分:9)

list是“动态增长的向量”(非常类似于C ++的std::vector,但是这绝不会减慢对它们的随机访问速度(它们不是链接的列表! - )。列表的条目是对Python对象(项目)的引用:访问一个只需要(在CPython中)项目引用计数的增量(在其他实现中,基于更高级的垃圾收集,甚至不是;-)。数组的条目是原始位和字节:访问一个条目需要根据该二进制值合成一个全新的Python对象。例如:

$ python -mtimeit -s'import array; c=array.array("B", "bzap")' 'c[2]'
10000000 loops, best of 3: 0.0903 usec per loop
$ python -mtimeit -s'c=list("bzap")' 'c[2]'
10000000 loops, best of 3: 0.0601 usec per loop

30纳秒的额外访问时间似乎并不太糟糕; - )。

顺便说一句,请注意timeit在命令行中使用更好 - 自动选择重复,时间显示的度量单位等等。这就是我总是使用它的方式(导入自定义)带有函数的编码模块,如果需要的话 - 但是这里没有必要 - - 它比那么比从模块导入和使用它更容易!

答案 1 :(得分:8)

将原始整数包装到Python int中需要花费时间。

答案 2 :(得分:1)

Python列表非常类似于普通数组的某些方式,它们不是Lisp列表,但它们具有快速随机访问。