我需要维护一个大型的Python可拾取对象列表。该列表太大,无法全部存储在RAM中,因此需要一些数据库/分页机制。我需要该机制支持快速访问列表中的接近(附近)区域。
该列表应实现所有Python列表功能,但大多数情况下我将按顺序工作:扫描列表中的某个范围,并在扫描过程中决定是否要在扫描点插入/弹出某些节点。
该列表可以非常大(2-3 GB),不应一次全部包含在RAM中。节点很小(100-200字节),但可能包含各种类型的数据。
这个问题的一个好解决方案是使用BTree,在其中只加载最后访问的桶到RAM中。
使用SQL表不好,因为我需要实现复杂的索引键机制。我的数据不是表格,而是一个简单的Python列表,具有在特定索引中添加元素和从特定位置弹出元素的功能。
我尝试了ZODB和zc.blist,它们实现了一种基于BTree的列表,可以存储在ZODB数据库文件中,但我不知道如何配置它,使得上述功能能够以合理的时间运行。 我不需要所有的多线程/事务特性。除了我的单线程程序,没有人会触碰数据库文件。 有人能否告诉我如何配置ZODB/zc.blist,使得以上功能快速运行,或者展示一个不同的大型列表实现? 以下是我尝试的一些简单而肮脏的代码:
该列表应实现所有Python列表功能,但大多数情况下我将按顺序工作:扫描列表中的某个范围,并在扫描过程中决定是否要在扫描点插入/弹出某些节点。
该列表可以非常大(2-3 GB),不应一次全部包含在RAM中。节点很小(100-200字节),但可能包含各种类型的数据。
这个问题的一个好解决方案是使用BTree,在其中只加载最后访问的桶到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,)
打印结束:
扩展到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秒 被杀死(不是我干的)