我有大约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, :]
随着逐行计时,我确定它绝对是随着时间的推移而减速的最后一行。
Upadte :绘制加载时间会产生不同的结果。有一次它看起来像这样,即降级不是渐进的,而是在恰好400个文件之后跳跃。这可能是操作系统的一些限制吗?
但另一次看起来完全不同:
经过几次测试后,第二个图似乎是性能开发的典型代表。
此外,我在循环后尝试del X
,没有任何影响。也没有通过mmap
工作来访问底层Python X._mmap.close()
。
有关为什么性能不一致的任何想法?有没有更快的商店和替代品的替代品?检索这些矩阵?
答案 0 :(得分:4)
硬盘驱动器很差,并且服务于多个主设备" - 减速可能比人们预期的要大得多。为了演示,我使用此代码读取我的Ubuntu 12.04机器的HDD上的备份文件(每个大约50 MB):
import os, random, time
bdir = '/hdd/backup/'
fns = os.listdir(bdir)
while True:
fn = random.choice(fns)
if not fn.startswith("duplicity-full."):
continue
ts = time.time()
with open(bdir+fn, 'rb') as f:
c = f.read()
print "MB/s: %.1f" %(len(c)/(1000000*(time.time()-ts)))
运行其中一个"进程"给了我不错的阅读表现:
MB/s: 148.6
MB/s: 169.1
MB/s: 184.1
MB/s: 188.1
MB/s: 185.3
MB/s: 146.2
并行添加第二个这样的过程会使事情减慢一个以上的数量级:
MB/s: 14.3
MB/s: 11.6
MB/s: 12.7
MB/s: 8.7
MB/s: 8.2
MB/s: 15.9
我的猜测是这个(即其他硬盘使用)是你性能不一致的原因。我的预感是SSD会做得更好。对于我的机器,对于SSD上的大文件,由于并行读取器进程导致的减速仅为两倍,从大约440 MB / s到大约220 MB / s。 (见我的评论。)
答案 1 :(得分:4)
您可以考虑使用bcolz。它压缩磁盘和内存中的数字数据以加快速度。您可能必须转置矩阵才能获得稀疏读取,因为bcolz按列而非行存储事物。