【发布时间】:2016-05-21 15:53:26
【问题描述】:
我在磁盘上存储了大约 700 个矩阵,每个矩阵大约有 70k 行和 300 列。
我必须将这些矩阵的 部分 相对较快地加载到内存中的另一个矩阵中,每个矩阵大约 1k 行。我发现最快的方法是使用内存映射,最初我能够在大约 0.02 秒内加载 1k 行。但是,性能根本不一致,有时每个矩阵的加载时间长达 1 秒!
我的代码大致是这样的:
target = np.zeros((7000, 300))
target.fill(-1) # allocate memory
for path in os.listdir(folder_with_memmaps):
X = np.memmap(path, dtype=_DTYPE_MEMMAPS, mode='r', shape=(70000, 300))
indices_in_target = ... # some magic
indices_in_X = ... # some magic
target[indices_in_target, :] = X[indices_in_X, :]
通过逐行计时,我确定它肯定是随着时间的推移减慢的最后一行。
更新:绘制加载时间会给出不同的结果。有一次它看起来像这样,即降级不是渐进的,而是在恰好 400 个文件之后跳跃。这可能是一些操作系统限制吗?
但另一次看起来完全不同:
经过几次测试后,第二个情节似乎是性能发展的典型。
另外,我在循环后尝试del X,没有任何影响。通过X._mmap.close() 访问底层Python mmap 也不起作用。
关于为什么性能不一致的任何想法?是否有更快的替代方法来存储和检索这些矩阵?
【问题讨论】:
-
当您移至下一个文件时,基础
mmap文件似乎没有被关闭。这是一个疯狂的猜测,但我会尝试在循环末尾添加一个del X。np.memmap的代码是 Python 可读的,但mmap.mmap的代码不是。 -
索引的范围是多少?它们是否已排序? IE。
indices_in_X是np.arange(1000)还是np.random.shuffe(np.arange(0, 70000, 70))很重要。另外,尝试使时间与操作系统文件缓存效果无关:unix.stackexchange.com/q/87908 -
@morningsun 感谢您的回复。我尝试对
indices_in_X和indices_in_target进行排序,我认为它略微改善了基线,但看似随机的退化补丁仍然存在。同样不幸的是,我正在使用共享服务器并且没有任何 sudo 权限,所以我无法清除任何缓存。 -
既然这是共享服务器,那么其他用户正在做的事情导致性能不一致的可能性有多大?如果有可能,是否有一段时间您可以在服务器上没有其他人的情况下测试您的代码?
-
这些加载时间是否包括程序启动,或者它们是否包含在您的代码中?您如何控制测试的文件数量?
标签: python performance unix numpy memory-mapped-files