【问题标题】:Python list memory reallocation issuePython列表内存重新分配问题
【发布时间】:2016-11-10 07:14:21
【问题描述】:

如果我使用 C-Python 或 jython(在 Python 2.7 中),并且对于 list ([]) 数据结构,如果我继续添加新元素,是否会出现内存重新分配问题,例如 Java ArrayList 有(由于Java ArrayList需要连续内存空间,如果当前预分配空间已满,则需要重新分配新的更大的连续大内存空间,并将现有元素移动到新分配的空间)?

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.ensureCapacity%28int%29

问候, 林

【问题讨论】:

  • Cpython 列表实现为数组列表,但 append 是摊销的常数时间。见here
  • 如果你会读 C,你应该看看 CPython 源代码listobject.c。保存指向 Python 列表项的指针的结构成员是 ob_item。当列表增长时,ob_item 可以重新分配,并且旧项目被复制,但这是在 C 级别发生的,所以速度很快。当然,Python 列表对象本身的内存位置不会受到影响。
  • @juanpa.arrivillaga,读后混淆了amortized 这里的意思,你能再澄清一下吗?
  • @PM2Ring,如果由于找不到连续的内存块而无法进行扩展,则执行重新分配的繁重操作 - 即移动到新位置需要 O(n) 时间(@ 987654330@是列表中的元素个数)?
  • 正如我之前所说,任何所需的复制都发生在 C 级别,因此它比 Python for 循环快得多。请记住,现代 CPU 具有用于复制数组的高效操作码。

标签: python python-2.7 list


【解决方案1】:

基本的故事,至少对于主要的 Python 来说,是一个列表包含指向内存中其他地方的对象的指针。该列表是用一定的空闲空间创建的(例如,对于 8 个指针)。当它填满时,它会分配更多的内存,依此类推。是否将指针从一个内存块移动到另一个内存块,是大多数用户忽略的细节。在实践中,我们只是根据需要附加/扩展一个列表,而不用担心内存使用。

Why does creating a list from a list make it larger?

我假设 jython 使用相同的方法,但您必须深入研究它的代码才能看到它如何转换为 Java。

我主要回答numpy 的问题。这是一个创建固定大小的多维数组的数值包。如果用户需要增量构建这样的数组,我们通常建议他们从列表开始并附加值。最后他们创建了数组。追加到列表比多次重建数组要便宜得多。

【讨论】:

  • 感谢 hpaulj,如果由于找不到连续的内存块而无法进行扩展,则执行重新分配的繁重操作 - 即移动到新位置需要 O(n) 时间(@ 987654325@ 是列表中元素的数量)?您可以阅读来自 shanmuga 的回复。如果我错了,请纠正我。
  • 但是O(n) 的举动在广泛的背景下有意义吗?解释器在后台不断地创建和销毁列表和字典。因此,偶尔调用realloc 在您的列表中执行此低级别移动可能不是速度瓶颈。
  • 您心目中的尺码表是多少?几百个数字?表示矩阵 1000x1000 的嵌套列表?迭代列表可能比添加新元素更昂贵。
  • hpaulj,感谢您的建议。我阅读了其他一些博客和讨论,有时我看到即使发生内存重新分配,摊销性能(考虑重新分配成本时)也是 O(1)。任何想法什么是摊销性能?
【解决方案2】:

在内部,python 列表是 hpaulj 提到的指针数组

接下来的问题是如何在 C 中扩展一个数组,如 answer 中所述。这说明这可以使用 C 中的 realloc 函数来完成。

这导致我查看提到的realloc 的行为

函数可能会将内存块移动到新位置(其地址由函数返回)。

据此,我的理解是如果连续内存可用,则数组对象被扩展,否则内存块(包含数组对象而不是列表对象)被复制到新分配的更大大小的内存块。

这是我的理解,如有错误欢迎指正。

【讨论】:

  • 感谢shanmuga,假设由于找不到连续的内存块而无法进行扩展,并且移动到新位置需要O(n)时间(n是列表中的元素数)?
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
  • 1970-01-01
  • 2011-07-18
  • 2010-11-21
  • 2011-01-07
相关资源
最近更新 更多