2

现在,我正在使用字符串、StringIO 或 cStringIO 缓冲字节。但是,我经常需要从缓冲区的左侧删除字节。一种天真的方法会重建整个缓冲区。如果左截断是一种非常常见的操作,是否有最佳方法来做到这一点?Python 的垃圾收集器实际上应该对截断的字节进行 GC。

任何类型的算法(将缓冲区分成小块?)或现有的实现,都会有帮助。

编辑:

我尝试为此使用 Python 2.7 的 memoryview,但遗憾的是,当删除原始引用时,“视图”之外的数据不会被 GC:

# (This will use ~2GB of memory, not 50MB)

memoryview # Requires Python 2.7+

smalls = []

for i in xrange(10):
    big = memoryview('z'*(200*1000*1000))
    small = big[195*1000*1000:]
    del big
    smalls.append(small)
    print '.',
4

2 回答 2

3

如果左删除操作频繁,则双端队列将是有效的(与使用列表、字符串或缓冲区不同,它的任一端删除的摊销为 O(1))。然而,它会比字符串更昂贵的内存,因为您将每个字符存储为其自己的字符串对象,而不是打包序列。

或者,您可以创建自己的实现(例如,固定大小的字符串/缓冲区对象的链接列表),它可以更紧凑地存储数据。

于 2009-06-17T11:49:41.343 回答
1

将缓冲区构建为字符或行列表,然后对列表进行切片。仅在输出时作为字符串加入。这对于大多数类型的“可变字符串”行为非常有效。

GC 将收集截断的字节,因为它们不再在列表中引用。

更新:要修改列表头,您可以简单地反转列表。这听起来像是一件低效的事情,但是 python 的列表实现在内部对此进行了优化。

来自http://effbot.org/zone/python-list.htm

反转很快,因此如果您需要在列表的开头删除和插入一堆项目,暂时反转列表通常可以加快速度:

L.reverse()
# append/insert/pop/delete at far end
L.reverse()
于 2009-06-17T10:25:03.340 回答