在 python 中,为啥从数组读取比从列表读取慢?

Posted

技术标签:

【中文标题】在 python 中,为啥从数组读取比从列表读取慢?【英文标题】:In python, why is reading from an array slower than reading from list?在 python 中,为什么从数组读取比从列表读取慢? 【发布时间】:2011-03-17 08:30:54 【问题描述】:

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

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

这是我的代码:

从 timeit 导入计时器 导入数组 t = 10000 l = 范围(t) a = array.array('i', l) 定义列表(): 对于 xrange(t) 中的 i: l[i] 定义数组(): 对于 xrange(t) 中的 i: 一个[我] 打印计时器(列表).timeit(1000); 打印计时器(数组).timeit(1000);

输出是:

0.813191890717 1.16269612312

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

有人解释一下吗?

【问题讨论】:

可能的欺骗/答案:***.com/questions/176011/… - 基本上 array.array 是一个 C 数组的包装器,所以我认为访问它时会有开销。不要用它来做数学。 试图猜测 Python 的效率——尤其是对于那些来自类 C 背景的人——通常是违反直觉的。先写清楚代码,然后在衡量性能问题时进行优化;这也适用于 C,但因为语言元素非常接近人们经常忘记的机器。 对于数学,你可能想使用 numpy(python 3 尚不可用),只有天知道为什么 numpy 不是标准库。 numpy 在 Python 3 上非常接近可用:mail-archive.com/numpy-discussion@scipy.org/msg26524.html 【参考方案1】:

lists 是“动态增长的向量”(很像 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 在命令行中使用起来更好——自动选择重复、显示时间的测量单位等。这就是我一直使用它的方式(导入自定义编码如果需要,带有要调用的函数的模块——但这里没有必要)——它如此比从模块中导入和使用它更方便!

【讨论】:

【参考方案2】:

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

【讨论】:

确实如此。函数 LIST 只需递增然后递减每个列表元素的引用计数。另一方面,ARRAY 函数必须为每个整数分配内存(除了具有优化的较小整数),然后再次释放它。【参考方案3】:

Python 列表在某些方面确实类似于普通数组,它们不是 Lisp 列表,但它们具有快速随机访问。

【讨论】:

以上是关于在 python 中,为啥从数组读取比从列表读取慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Hadoop SequenceFile 写入比读取慢得多?

为啥在 C++ 中从标准输入读取行比 Python 慢得多?

为啥在 C++ 中从标准输入读取行比 Python 慢得多?

为啥从队列中并行读取消息很慢?

在python3中,如果给定数组的大小,如何从单行输入中读取一个整数数组?

在 Visual Studio 中发布版本 Ctrl+F5 比从外部 VS 慢 10 倍 [关闭]