代码之家  ›  专栏  ›  技术社区  ›  Jason Dagit

对于从磁盘以恒定空间使用流式传输数据,最有效的习惯用法是什么?

  •  2
  • Jason Dagit  · 技术社区  · 16 年前

    问题描述

    我需要从磁盘上传输大文件。假设文件比内存中的文件大。此外,假设我对数据做了一些计算,结果足够小,可以放入内存。作为一个假设的例子,假设我需要计算一个200GB文件的md5sum,并且我需要保证使用多少ram。

    总而言之:

    • 需要固定的空间
    • 越快越好
    • 结果符合记忆

    问题

    使用恒定空间从文件中读取/传输数据的最快方法是什么?

    我的想法

    如果文件足够小,可以放入内存,那么 mmap 在POSIX系统上会非常快,不幸的是,这里不是这样。使用有什么性能优势吗 mmap公司 用较小的缓冲区大小来缓冲文件的连续块?系统会调用移动 mmap公司 缓冲下来的文件占主导地位的任何优势,还是我应该使用一个固定的缓冲区,我读入 fread ?

    3 回复  |  直到 16 年前
        1
  •  3
  •   Jeff Foster    16 年前

    我不太确定 mmap 会非常快(其中非常快定义为明显快于 fread

    格雷普以前用过 mmap公司 ,但切换回 弗雷德 page 讨论了一些关于这个的历史。

    您可以将系统上的性能与选项进行比较 --mmap 去格雷普。在我的系统上,200GB文件的性能差异可以忽略不计,但您的里程数可能会有所不同!

    弗雷德 具有固定大小的缓冲区。它的代码更简单,更容易处理错误,而且几乎肯定会足够快。

        2
  •  0
  •   mjv    16 年前

    根据您使用的语言,基于您为其声明了特定缓冲区大小的文件的类C fread()循环将完全需要此缓冲区大小,而不是更多或更少。

    我们通常选择4到128千字节的缓冲区大小,如果有较大的缓冲区,几乎没有任何增益。

    如果性能是非常重要的,为了获得相对较少的收益(并且冒着重新发明某些东西的风险),可以考虑使用双线程实现,即一个线程在一组两个缓冲区中读取文件,另一个线程以顺序方式一次在其中一个缓冲区中执行计算。这样可以消除磁盘访问延迟。

        3
  •  0
  •   Mike Dunlavey    16 年前

    mjv是对的。您可以使用双缓冲区和重叠I/O,这样您的压缩和磁盘读取可以同时进行。然后,我会对嘎吱嘎吱声进行轮廓或叠加拍摄,使其尽可能快。如果幸运的话,它将比I/O更快,因此您将以最快的速度运行I/O而不会停顿。然后像文件碎片这样的事情就出现了。