我有大量的大整数数组存储在hdf5 5格式的文件中。我发现将这些数据表示为dask数组(相对于h5py.File对象列表)是方便的数据索引,但是从磁盘加载数据片非常缓慢。
下面是一个示例,其中dsets是h5py.File对象的列表,x是由这些h5py.File对象构造的dask.array。dask数组的分块与h5py.File对象的块匹配。
# Index h5py objects individually
In [68]: %%time
...: tmp = [d[0,0,0] for d in dsets];
...:
CPU times: user 23.6 ms, sys: 3.97 ms, total: 27.6 ms
Wall time: 26.8 ms
# Index dask array
In [69]: %%time
...: tmp = x[:,0,0,0].compute()
...:
CPU times: user 2.72 s, sys: 187 ms, total: 2.9 s
Wall time: 2.87 s什么解释了加载相同数据的100倍的时间差异?我能做些什么来降低达斯克的载货时间吗?
编辑:这是我用jupyter笔记本制作的一个存储库,它将一些假数据保存到磁盘上作为*.h5 files,然后将加载性能与原始h5py或dask进行比较(与块匹配)。在这些测试中,我发现用h5py在循环中加载数据的速度比dask中的等效操作快8-10倍。
发布于 2017-09-09 23:47:29
HDF5文件的读取性能差通常是由于文件块的方式与dask.array块的方式不匹配造成的。
例如,在极端情况下,如果HDF5文件按行分块,而dask.array逐列读取块,那么每个块都读取整个文件,这很容易导致100倍的减速。
因此,您应该检查h5py.Dataset对象的块
>>> d.chunks
(100, 100, 100)并且您应该将from_array调用与这些块对齐。
>>> x = da.from_array(x, chunks=(100, 100, 100))或者,如果这些块小于最佳值,则应该尝试将块大小设计为每个维度中的整数倍数。
>>> x = da.from_array(x, chunks=(100, 200, 300))如果您的数据集没有分块
>>> d.chunks
None然后,您的数据集按C顺序排列,您应该避免在后面的维度中分块。
>>> x = da.from_array(x, chunks=(5, None, None))您应该选择足够大的块大小,以隐藏任务调度的开销。达斯克的开销为每块几百微秒。如果你的块很小,那么这个开销就会占主导地位。我通常拍摄的块大小约为100 in,尽管应用程序的大小差别很大。
https://stackoverflow.com/questions/46134491
复制相似问题