【问题标题】:Hdf5 file reading speed slowing down suddenlyhdf5文件读取速度突然变慢
【发布时间】:2022-01-24 16:47:03
【问题描述】:

我正在尝试遍历 hdf5 文件。该文件由一系列“时间戳”组成,每个时间戳都有可变数量的“玩家”,我想从中获取数据。该文件非常大,有超过 17k 的时间戳,我观察到在经过数百次迭代后,获取“players = list(data[timestamp].keys())”所花费的时间从大约 0.0005 秒突然增加了很多大约为 0.05。

        with h5py.File(self.hdf5file, "r") as f:
            data = f['data']
            timestamps = list(data.keys())
            for timestamp in timestamps:
                start_time = time.time()
                players = list(data[timestamp].keys())
                end_time = time.time()
                print(end_time - start_time)

我不知道会发生什么以及如何解决它。

【问题讨论】:

  • 不是一个答案,而是一个可能有帮助的建议。假设你有足够的内存可以尝试:with h5py.File(self.hdf5file, driver='core') as f:
  • @JCaesar 感谢您的评论。你介意解释一下这是做什么的吗?
  • 将整个 hdf5 文件读入内存
  • 哦,好的,在这种情况下不能这样,因为文件很大(50gb)
  • 无需创建列表来迭代组和数据集。您可以像这样遍历名称/键:for timestamp in data.keys():for players in data[timestamp].keys():

标签: python pytorch hdf5 h5py


【解决方案1】:

我怀疑还有比您的简单示例捕获的更多内容。当您只是读取键以获取组和数据集名称时,它不应显示性能下降。

为了演示,我编写了一个示例,该示例创建了一个模仿您的架构的文件。创建文件后,它会以只读模式关闭并重新打开,然后循环访问每个时间戳组和播放器数据集并打印访问时间。所有时间步长的响应时间始终很短。 [示例文件为 1.4 GB。如果您想测试更大的文件,请增加 arr 的大小。] 仅供参考,我是在具有 24 GB RAM 的 Windows 系统上运行的。

代码如下:

ntimes = 10000
nplayers = 10
hdf5file = 'SO_70466356.h5'
start_time = time.time()
with h5py.File(hdf5file, "w") as h5f:
    data = h5f.create_group('data')
    for t_cnt in range(ntimes):
        grp = data.create_group(f'time_{t_cnt:05}')
        for p_cnt in range(nplayers):
            arr = np.random.random(300*3).reshape(300,3)
            grp.create_dataset(f'player_{p_cnt:02}',data=arr)
print(f'HDF5 file creation time: {time.time()-start_time:.4f}')            

print(f'HDF5 file read times')            
with h5py.File(hdf5file, "r") as h5f:
    data = h5f['data']
    start_time = time.time()
    timestamps = list(data.keys())
    for cnt,timestamp in enumerate(timestamps):            
        players = list(data[timestamp].keys())
        if not (cnt+1)%1000 :
            print(f'For {timestamp}: {time.time()-start_time:.4f}')
            start_time = time.time()

上面的输出:

HDF5 file creation time: 29.7558
HDF5 file read times
At time_00999: 0.1766
At time_01999: 0.1736
At time_02999: 0.1650
At time_03999: 0.1872
At time_04999: 0.1716
At time_05999: 0.1740
At time_06999: 0.1716
At time_07999: 0.1716
At time_08999: 0.1720
At time_09999: 0.1872

【讨论】:

  • 您好,谢谢您的回答。有趣的是,当我运行您的代码时,也会出现同样的减速!我设置了 ntimes = 10000 和 nplayers = 10。创建文件需要 249.13。部分经过时间: 对于 time_02699:0.00008 对于 time_02799:0.00008 对于 time_02899:对于 time_02999:0.03894 对于对于 time_03099:对于 time_03199:0.02930 对于对于 time_03199:对于 time_03299:对于 time_03299:0.06007
  • 啊,我把 if not (cnt+1)%1000 改成了 if not (cnt+1)%100。我在 jupyterlab 上的 ubuntu 上运行它
  • 好的,我尝试在 jupyterlab 之外运行它一段时间。我注意到迭代开始变慢的点基本上是上一次运行的最后一次迭代。所以我猜有些东西被缓存了,所以之前访问过的迭代以后会更快。
  • 我刚刚意识到我没有包含ntimesnplayers 的行。对不起!代码已更新以更正。我最初使用ntimes=20000nplayers=10 运行。我进行了修改以匹配您的值并更改了时间打印输出,因此它总共超过 1000 个时间戳。输出添加到我上面的答案中。如您所见,读取每 1000 个时间戳的时间几乎相同(范围从 0.1650 到 0.1872 秒)。另外,我创建文件的时间比你的快得多。显然,我们的 2 h/w 或 s/w 配置有所不同。
  • 出于好奇,我在 repl.it 虚拟机上运行了它。 (它只有 500MB RAM 和 500MB 存储,所以我减少到 ntimes=5000nplayers=10。行为类似于我的 Windows W/S。读取 500 个时间戳的时间仅显示出一些变化,但并没有变慢(范围从 0.1292 到 0.2180 秒,最后 2 个增量都是 0.1489 秒)。因此,看起来 RAM 量不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 2014-04-18
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 2021-11-21
相关资源
最近更新 更多