我有一个大的(75000 x 5 x 6000)3D数组存储为NumPy存储器映射。如果我像这样简单地遍历第一维:
import numpy as np
import time
a = np.memmap(r"S:\bin\Preprocessed\mtb.dat", dtype='float32', mode='r', shape=(75000, 5, 6000))
l = []
start = time.time()
index = np.arange(75000)
np.random.shuffle(index)
for i in np.array(index):
l.append(np.array(a[i]) * 0.7)
print(time.time() - start)
>>> 0.503
迭代很快发生。但是,当我尝试在较大程序的上下文中迭代同一个memmap时,对memmap的单独调用将花费0.1秒,并且拉动所有75000条记录将花费将近10分钟。
较大的程序在这里重现的时间太长,所以我的问题是:是否有任何已知的问题可能导致memmap访问速度显着降低,也许如果Python内存中存有大量数据?/ p>
在较大的程序中,用法如下:
import time
array = np.memmap(self.path, dtype='float32', mode='r', shape=self.shape)
for i, (scenario_id, area) in enumerate(self.scenario_areas):
address = scenario_matrix.lookup.get(scenario_id)
if address:
scenario_output = array[address]
output_total = scenario_output * float(area)
cumulative += output_total # Add results to cumulative total
contributions[int(scenario_id.split("cdl")[1])] = output_total[:2].sum()
del array
第二个例子执行时间超过10分钟。定位行 scenario_output = array [address] ,它只是从memmap中提取记录,在0.0到0.5之间变化 - 半秒来拉取单个记录。< / p>
答案 0 :(得分:1)
据我所知,python中的memmaps没有任何限制,可以独立于一般的os级别限制。所以我猜你要么有一个os级别的内存瓶颈(可能是缓存不同的大型mmaps之间的交互),要么你的问题就在其他地方。
非常好的是,您已经有一个参考实现,它显示了应该的运行速度。您需要系统地测试不同的可能原因。以下是一些有助于确定原因的方向。
首先,在参考实现上使用cProfile,以便更好地了解瓶颈所在。您将获得函数调用的列表以及每个函数所花费的时间。这可能会导致意外结果。一些猜测:
self.scenario_areas
列表式还是迭代器执行一些隐藏且昂贵的计算?scenario_matrix.lookup.get(scenario_id)
很慢。检查一下。contributions
是一个常规的python列表或字典,还是在幕后分配时做了什么奇怪的事?只有当您确认时间实际上花费在scenario_output = array[address]
行中时,才会开始假设mmap文件之间的交互。如果是这种情况,请开始注释掉涉及其他内存访问的代码部分,并重复编写代码,以便更好地了解发生的情况。
我希望这会有所帮助。
答案 1 :(得分:0)
您可能无法使用np.memmap,
来避免性能问题我建议尝试类似https://turi.com/products/create/docs/generated/graphlab.SFrame.html
的内容SFrame / SArray允许您直接从磁盘读取表格数据,对于大型数据文件通常会更快。
获取