【发布时间】:2010-03-24 17:59:34
【问题描述】:
我需要维护大量 python 可腌制对象。列表太大,无法全部存储在 RAM 中,因此需要一些数据库\分页机制。我需要该机制支持快速访问列表中的近距离(附近)区域。
列表应该实现所有 python-list 功能,但大多数时候我会按顺序工作:扫描列表中的一些范围,并在扫描时决定是否要在扫描点插入\弹出一些节点。
该列表可能非常大(2-3 GB),不应一次全部包含在 RAM 中。 节点很小(100-200 字节),但可以包含各种类型的数据。
一个很好的解决方案可能是使用 BTree,其中只有最后访问的存储桶被加载到 RAM 中。
使用 SQL 表并不好,因为我需要实现复杂的索引键机制。 我的数据不是表格,它是一个简单的python列表,具有在特定索引中添加元素以及从特定位置弹出元素的功能。
我尝试了ZODB 和zc.blist,它们实现了一个可以存储在ZODB 数据库文件中的基于BTree 的列表,但我不知道如何配置它,以便上述功能可以在合理的时间内运行。 我不需要所有的多线程\事务处理功能。除了我的单线程程序,没有人会接触数据库文件。
谁能解释我如何配置 ZODB\zc.blist 以使上述功能能够快速运行,或者向我展示一个不同的大列表实现?
我尝试过的一些快速而肮脏的代码:
import time
import random
NODE_JUMP = 50000
NODE_ACCESS = 10000
print 'STARTING'
random_bytes = open('/dev/urandom', 'rb')
my_list = list()
nodes_no = 0
while True:
nodes_no += NODE_JUMP
start = time.time()
my_list.extend(random_bytes.read(100) for i in xrange(NODE_JUMP))
print 'extending to %s nodes took %.2f seconds' % (nodes_no, time.time() - start)
section_start = random.randint(0, nodes_no -NODE_ACCESS -1)
start = time.time()
for index in xrange(section_start, section_start + NODE_ACCESS):
# rotate the string
my_list[index] = my_list[index][1:] + my_list[index][0]
print 'access to %s nodes took %.2f seconds' % (NODE_ACCESS, time.time() - start,)
打印结束于:
扩展到 5000000 个节点耗时 3.49 秒 访问 10000 个节点耗时 0.02 秒 扩展到 5050000 个节点耗时 3.98 秒 访问 10000 个节点耗时 0.01 秒 扩展到 5100000 个节点耗时 2.54 秒 访问 10000 个节点耗时 0.01 秒 扩展到 5150000 个节点耗时 2.19 秒 访问 10000 个节点耗时 0.11 秒 扩展到 5200000 个节点耗时 2.49 秒 访问 10000 个节点耗时 0.01 秒 扩展到 5250000 个节点耗时 3.13 秒 访问 10000 个节点耗时 0.05 秒 被杀(不是我)【问题讨论】:
-
400MB 多大?你的电脑有多少内存?
-
假设它可以达到2GB。我不希望它浪费所有的内存资源。
-
我第一次尝试将 4,000,000 个 100 字节的对象放入字典中产生了一个消耗 900MB 的 python 进程。耗时几十秒,访问字典的时间基本是瞬间的。
-
我的程序中需要大约 10 个这样的列表。