为什么读取整个hdf5数据集比切片更快

时间:2018-11-24 13:26:38

标签: python io hdf5 h5py

我试图弄清楚为什么会发生这种情况:

arbitraryLetter :: Gen Letter
arbitraryLetter = elements [G, B]

如您所见,将整个数据集加载到内存中然后进行切片比从数据集中获取相同的切片要快。

块大小与切片匹配,所以它应该都是连续的内存,对吗?那为什么它这么慢?

数据集使用gzip(In [1]: import time, h5py as h5 In [2]: f = h5.File('myfile.hdf5', 'r') In [3]: st = time.time(); data = f["data"].value[0,:,1,...]; elapsed = time.time() - st; In [4]: elapsed Out[4]: 11.127676010131836 In [5]: st = time.time(); data = f["data"][0,:,1,...]; elapsed2 = time.time() - st; In [6]: elapsed2 Out[6]: 59.810582399368286 In [7]: f["data"].shape Out[7]: (1, 4096, 6, 16, 16, 16, 16) In [8]: f["data"].chunks Out[8]: (1, 4096, 1, 16, 16, 16, 16) )压缩。

按照安德鲁的评论,我运行它来清除两次读取之间的缓存:

opts=2

(下一次运行两次读取之间有10秒的延迟以清除缓存)

elapsed1: 11.001180410385132
elapsed2: 43.19723725318909
48.61user 4.45system 0:54.65elapsed 97%CPU (0avgtext+0avgdata 8431596maxresident)k
479584inputs+0outputs (106major+3764414minor)pagefaults 0swaps

1 个答案:

答案 0 :(得分:1)

首先,我对自己进行了测试。我没有您的HDF5文件,因此请使用我的测试文件之一。我的测试表数据集有约54,000行(似乎比您的行大)。
.value []的计时结果给出

>>> elapsed
0.15540122985839844

使用NumPy索引的定时结果给出:

>>> elapsed2
0.12980079650878906

因此,我认为性能没有太大差异。可能与我们正在测试的数据集大小有关,还是与数据表的复杂性有关?

对h5py最新文档的一些阅读对Dataset.value有一些有趣的评论(来自2.8.0版-2018年6月5日;重点是我的):
Dataset.value属性现已弃用。
可以追溯到h5py 1.0的属性Dataset.value已弃用,并将在以后的版本中删除。 此属性将整个数据集转储到NumPy数组中。 使用.value的代码应更新为使用mydataset[...]或{{1 }}。

您的计时测试似乎与上面突出显示的观察相反。

我认为您需要请h5py开发人员对性能差异(以及数据存储在内存和磁盘上)进行评论。您是否已检查h5py user group

编辑: 发布后,我发现了此问题与解答。它有很多不错的评论,还包括h5py开发人员的回应:
h5py: Correct way to slice array datasets