我使用偏移量访问 LMDB 数据库中的元素,但速度太慢了。这是为什么?
I use an offset to access elements in LMDB database but it is so slow. Why is that?
我已将我的完整 LMDB 数据库放入一个非常大的 key/value 字节串数组,该数组与一个键(我的 LMDB 数据库中唯一的键)相关联。因此,我通过偏移量访问所需的值,正如您在代码片段中看到的那样,偏移量是数组中的索引。有了这样的结构,我的访问时间应该是 O(1)。问题是当我查询我的数据库时它太慢了。我完全不知道为什么要花这么长时间。首先将我的大数组存储在一个键中是个好主意吗? python 中是否有一种特殊的机制使得通过数组中的索引访问元素如此缓慢?数据不连续?我正在努力找出问题所在,请帮忙!
env = lmdb.open('light')
with env.begin(write=False,buffers=True) as txn:
cursor=txn.cursor()
cursor.first()
for i in range(18000000): #I have around 180000 element
cursor.value()[4*i:4*i+4] #this loop last an eternity
我认为问题是 cursor.value()
很贵。我不太了解 LMDB 的内部结构或其 Python 绑定,不知道它需要做多少工作,但它可能会进行部分 B 树遍历,调用 OS 来设置建立内存映射,构造复杂的代理对象,甚至可能将整个数组从 LMDB 复制到 Python 缓冲区对象中。而且您在循环的每次迭代中都调用它,因此它每次都必须重复该工作。销毁 cursor.value()
返回的对象也可能很昂贵,而且您每次都在重复这项工作。
如果我是对的,您应该能够通过将 value()
的调用提升到循环之外来获得显着的加速:
env = lmdb.open('light')
with env.begin(write=False,buffers=True) as txn:
cursor=txn.cursor()
if cursor.first():
data = cursor.value()
for i in range(18000000):
data[4*i:4*i+4]
Python 的解释器不是很有效,它的字节码编译器也没有做很多优化,所以你可能会看到使用三参数 range
的小但可测量的进一步加速为了避免在每次循环迭代中都必须乘以 4 两次:
env = lmdb.open('light')
with env.begin(write=False,buffers=True) as txn:
cursor=txn.cursor()
if cursor.first():
data = cursor.value()
for i in range(0, 18000000*4, 4):
data[i:i+4]
我已将我的完整 LMDB 数据库放入一个非常大的 key/value 字节串数组,该数组与一个键(我的 LMDB 数据库中唯一的键)相关联。因此,我通过偏移量访问所需的值,正如您在代码片段中看到的那样,偏移量是数组中的索引。有了这样的结构,我的访问时间应该是 O(1)。问题是当我查询我的数据库时它太慢了。我完全不知道为什么要花这么长时间。首先将我的大数组存储在一个键中是个好主意吗? python 中是否有一种特殊的机制使得通过数组中的索引访问元素如此缓慢?数据不连续?我正在努力找出问题所在,请帮忙!
env = lmdb.open('light')
with env.begin(write=False,buffers=True) as txn:
cursor=txn.cursor()
cursor.first()
for i in range(18000000): #I have around 180000 element
cursor.value()[4*i:4*i+4] #this loop last an eternity
我认为问题是 cursor.value()
很贵。我不太了解 LMDB 的内部结构或其 Python 绑定,不知道它需要做多少工作,但它可能会进行部分 B 树遍历,调用 OS 来设置建立内存映射,构造复杂的代理对象,甚至可能将整个数组从 LMDB 复制到 Python 缓冲区对象中。而且您在循环的每次迭代中都调用它,因此它每次都必须重复该工作。销毁 cursor.value()
返回的对象也可能很昂贵,而且您每次都在重复这项工作。
如果我是对的,您应该能够通过将 value()
的调用提升到循环之外来获得显着的加速:
env = lmdb.open('light')
with env.begin(write=False,buffers=True) as txn:
cursor=txn.cursor()
if cursor.first():
data = cursor.value()
for i in range(18000000):
data[4*i:4*i+4]
Python 的解释器不是很有效,它的字节码编译器也没有做很多优化,所以你可能会看到使用三参数 range
的小但可测量的进一步加速为了避免在每次循环迭代中都必须乘以 4 两次:
env = lmdb.open('light')
with env.begin(write=False,buffers=True) as txn:
cursor=txn.cursor()
if cursor.first():
data = cursor.value()
for i in range(0, 18000000*4, 4):
data[i:i+4]