我需要维护大量的python pickleable对象。该列表太大而无法全部存储在RAM中,因此需要一些数据库\分页机制。我需要该机制支持快速访问列表中的近距离(附近)区域。在python中维护大型列表
该列表应该实现所有python-list功能,但大多数时候我将按顺序工作:扫描列表中的某个范围,并在扫描时决定是否要在扫描点中插入\弹出一些节点。
该列表可能非常大(2-3 GB),并且不应该一次全部包含在RAM中。 节点很小(100-200字节),但可以包含各种类型的数据。
对此的很好的解决方案,可以使用B树,其中只有最后访问桶在RAM中。
使用SQL表并不好,因为我需要实现一个复杂的索引键机制。 我的数据不是一张表,它是一个简单的python列表,具有在特定索引中添加元素以及从特定位置弹出元素的功能。
我试过ZODB和zc.blist,它们实现了基于BTree的列表,可以存储在ZODB数据库文件中,但我不知道如何配置它以便上述功能在合理的时间内运行。 我不需要所有的多线程\交易功能。除了我的单线程程序外,其他人都不会触及数据库文件。
任何人都可以解释我如何配置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,)
打印止带:
extending to 5000000 nodes took 3.49 seconds access to 10000 nodes took 0.02 seconds extending to 5050000 nodes took 3.98 seconds access to 10000 nodes took 0.01 seconds extending to 5100000 nodes took 2.54 seconds access to 10000 nodes took 0.01 seconds extending to 5150000 nodes took 2.19 seconds access to 10000 nodes took 0.11 seconds extending to 5200000 nodes took 2.49 seconds access to 10000 nodes took 0.01 seconds extending to 5250000 nodes took 3.13 seconds access to 10000 nodes took 0.05 seconds Killed (not by me)
400MB大怎么样?你的电脑有多少内存? – 2010-03-24 19:43:12
假设它可以达到2GB。我不希望它浪费所有的内存资源。 – Oren
我第一次尝试将4,000,000个100字节的对象放入字典中,产生了一个耗费900MB的python进程。所花费的时间是几十秒,并且对字典的访问时间基本上是即时的。 –