我有一个很大的(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内存中保留了大量数据?
在较大的程序中,用法如下所示:
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
第二个示例需要十多分钟才能执行。只是将记录从memmap中拉出的脚本方案方案censing_output = array [address]的时间在0.0到0.5之间-半秒以拉出一条记录。
最佳答案
据我所知,没有任何可归因于python中memmap的限制,这些限制独立于一般的os级限制。因此,我想您可能是操作系统级别的内存瓶颈(可能是不同的大型mmap的缓存之间的交互),或者您的问题出在其他地方。
很好,您已经有一个参考实现,可以显示操作应该有多快。您将需要系统地测试不同的可能原因。以下是一些有助于确定原因的说明。
首先,在参考实现和上都使用cProfile,以更好地了解瓶颈在哪里。您将获得函数调用列表以及每个函数所花费的时间。这可能会导致意外的结果。一些猜测:
确实大部分时间都花在了您已发布的代码段中吗?如果不是这样,则分析可能会提示另一个方向。self.scenario_areas
是列表式的还是迭代器执行一些隐藏且昂贵的计算?
查找scenario_matrix.lookup.get(scenario_id)
可能很慢。核实。contributions
是常规的python列表或dict,还是在幕后分配时做任何奇怪的事情?
仅当您确认确实在scenario_output = array[address]
行中花费了时间时,我才开始假设mmap文件之间的交互。如果是这种情况,请开始注释掉涉及其他内存访问的部分代码,并反复分析该代码,以更好地了解发生的情况。
我希望这有帮助。
关于python - NumPy memmap性能问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42864320/