【问题标题】:Efficiently exporting floating-point numbers to a CSV file [closed]有效地将浮点数导出到 CSV 文件 [关闭]
【发布时间】:2021-10-07 13:51:59
【问题描述】:

出于预计算的目的,我需要将大量(数千万)单精度浮点数存储在一个逗号分隔的文件中。

我的表现优先级按以下顺序排列:

  1. 阅读速度
  2. 文件大小
  3. 写作速度

现在我只是在写数字的字符串表示,这显然可以改进。有什么好的方法可以做到这一点?

【问题讨论】:

  • CSV 文件根据定义是基于文本的 文件。字符串表示是唯一有效的形式; 不要将二进制数据存储在 CSV 文件中。如果不必是 CSV,您可能想研究 BSON。但也许您最好的解决方案是按原样写入二进制数据

标签: c# csv optimization compression


【解决方案1】:

最快和最有效的解决方案(文件大小)是以二进制格式存储二进制数据。粗略的线条(未以任何方式优化):

private static IEnumerable<float> read()
{
    using (var file = new FileStream(//whatever)
    using (var reader = new BinaryReader(file))
    {
        while (file.Position < file.Length)
            yield return reader.ReadSingle();
    }
}

private static void write(IEnumerable<float> ff)
{
    using (var file = new FileStream(//whatever)
    using (var writer = new BinaryWriter(file))
    {
        foreach (var f in ff)
            writer.Write(f);
    }
}

如果您需要保持 csv 格式,那么在写入和读取浮点数的文本表示方面确实没有任何选择,这使得该过程相当缓慢并且文件大小可能会大几个数量级。

【讨论】:

    【解决方案2】:

    对于您的 #2 目标,您需要知道数字的哪些部分实际上很重要,以及是否存在相关性。它们的范围是否受到限制?测量它们的准确度是多少?所有六位数都重要吗?这是一个连续数字之间差异很小的时间序列吗?

    该信息可用于压缩浮点值序列。限制它们值所代表的范围和精度。如果存在相关性,您可以获取连续值之间的差异并仅发送那些(第一个除外)。或者你可以有一个更复杂的模型来预测下一个给定序列的下一个数字,并发送每个数字的实际值和预测值之间的差异。

    然后你可以尝试使用标准的无损压缩器压缩结果,例如 gzip、zlib、zstd、lz4 等。

    所有这些都会产生一个紧凑的二进制文件。如果您确实需要结果是可读的 .csv,您仍然可以限制精度并进行差异编码,以提供一些压缩。然后需要在另一端撤消差异编码。

    【讨论】:

      猜你喜欢
      • 2019-10-31
      • 2014-09-30
      • 2018-11-05
      • 2019-11-25
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2011-05-17
      相关资源
      最近更新 更多