NumPy memmap性能问题

时间:2017-03-17 18:02:22

标签: python numpy numpy-memmap

我有一个大的(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

第二个例子执行时间超过10分钟。定位行 scenario_output = array [address] ,它只是从memmap中提取记录,在0.0到0.5之间变化 - 半秒来拉取单个记录。< / p>

2 个答案:

答案 0 :(得分:1)

据我所知,python中的memmaps没有任何限制,可以独立于一般的os级别限制。所以我猜你要么有一个os级别的内存瓶颈(可能是缓存不同的大型mmaps之间的交互),要么你的问题就在其他地方。

非常好的是,您已经有一个参考实现,它显示了应该的运行速度。您需要系统地测试不同的可能原因。以下是一些有助于确定原因的方向。

首先,在参考实现上使用cProfile,以便更好地了解瓶颈所在。您将获得函数调用的列表以及每个函数所花费的时间。这可能会导致意外结果。一些猜测:

  1. 大部分时间花在您发布的代码段中是真的吗?如果没有,分析可能暗示另一个方向。
  2. self.scenario_areas列表式还是迭代器执行一些隐藏且昂贵的计算?
  3. 可能是查找scenario_matrix.lookup.get(scenario_id)很慢。检查一下。
  4. contributions是一个常规的python列表或字典,还是在幕后分配时做了什么奇怪的事?
  5. 只有当您确认时间实际上花费在scenario_output = array[address]行中时,才会开始假设mmap文件之间的交互。如果是这种情况,请开始注释掉涉及其他内存访问的代码部分,并重复编写代码,以便更好地了解发生的情况。

    我希望这会有所帮助。

答案 1 :(得分:0)

您可能无法使用np.memmap,

来避免性能问题

我建议尝试类似https://turi.com/products/create/docs/generated/graphlab.SFrame.html

的内容

SFrame / SArray允许您直接从磁盘读取表格数据,对于大型数据文件通常会更快。

它是开源的,可在https://github.com/turi-code/SFrame

获取