如何有效地将数据附加到 C 中的 HDF5 表?

Posted

技术标签:

【中文标题】如何有效地将数据附加到 C 中的 HDF5 表?【英文标题】:How to efficiently append data to an HDF5 table in C? 【发布时间】:2013-11-28 23:57:44 【问题描述】:

我无法有效地将大量浮点值数据集保存在 HDF5 文件中。

数据采集工作如下: 创建一个固定的“射线数据”阵列(坐标、方向、波长、强度等)并将其发送到外部射线跟踪程序(其大约 2500 个值)。 作为回报,我得到了相同的数组,但数据发生了变化。 我现在想将新坐标保存在 HDF5 中以作为简单表格进行进一步处理。 这些步骤重复了很多次(大约 80 000 次)。

我按照 HDF5group http://www.hdfgroup.org/ftp/HDF5/current/src/unpacked/examples/h5_extend_write.c 的例子,但不幸的是解决方案很慢。

在我将数据直接写入 hdf5 文件之前,我使用了一个简单的 csv 文件,重复 100 次大约需要 80 秒,而附加到 hdf5 文件需要 160 秒。

“伪”代码如下所示:

//n is a large number e.g. 80000 
for (i=0;i<n;++i):

    /*create an array of rays for tracing*/
    rays = createArray(i);
    /*trace the rays*/
    traceRays(&rays);
    /* write results to hdf5 file, m is a number around 2500 */
    for(j=0;j<m;j++):
    
        buffer.x = rays[j].x
        buffer.y = rays[j].y
        //this seems to be slow: 
        H5TBappend_records(h5file,tablename, 1,dst_size, dst_offset, dst_sizes, &buffer)
        // this is fast:
        sprintf(szBuffer, "%15.6E,%14.6E\n",rays[j].x,rays[j].y)
        fputs(szBuffer, outputFile)
    

我可以想象它与每一步扩展表格的开销有关吗? 任何帮助将不胜感激。

干杯, 朱利安

【问题讨论】:

我不熟悉 HDF5 的 API,但 1H5TBappend_records 调用中是否告诉它为另一条记录分配空间?如果是这样,您可以将其移至 traceRays 附近并使用 m 将它们分配到大(r)块中。 是的,确实如此。将它移到外循环并分配一个更大的块有很大帮助!谢谢!现在大约是 120 秒而不是 180 秒,但仍然比将其写入 csv 文件要慢。 你还有什么可以向上移动并以更大的块做的吗?例如,数据的批处理副本,现在您已经分配了许多行。 【参考方案1】:

您可以使用 HDF5 的低级 API 获得非常好的性能。我在this detailed answer中解释了如何做到这一点。

基本上,如果您事先知道其最终大小(最佳情况),您需要使用固定大小的数据集,或者使用可以随意扩展的分块数据集(更多代码、更多开销和选择良好的块大小对性能至关重要)。在任何情况下,您都可以让 HDF5 库为您缓冲写入。应该很快。

在您的情况下,您可能想要创建一个复合数据类型来保存 table 的每个 record。然后,您的数据集将是您的复合数据类型的一维数组。

注意:您链接到的示例代码中使用的方法是正确的。如果它不适合你,那可能是因为你的块太小了。

【讨论】:

以上是关于如何有效地将数据附加到 C 中的 HDF5 表?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中有效地将数据插入 MySQL 中的多个表中

将浮点数组写入和附加到 C++ 中 hdf5 文件中的唯一数据集

如何在 hdf5 中有效地保存 python pandas 数据帧并将其作为 R 中的数据帧打开?

HDF5:如何将数据附加到数据集(可扩展数组)

从 HDF5 获取表索引的最有效方法

使用 Pandas、Python 将数据附加到 HDF5 文件