【问题标题】:Fast file reading快速文件读取
【发布时间】:2012-01-10 19:50:30
【问题描述】:

如果我是对的,在 Linux(C/C++, gcc/g++)上,可以使用 read(2)mmap(2) 系统调用从常规文件中读取数据。

两个问题。 read 系统调用是否在内部使用 mmap?什么时候第一个比第二个快,反之亦然?

【问题讨论】:

  • 你能告诉我们你的文件有多大,你有多少个文件?
  • 可能最好的办法是尝试两种方法,看看哪种方法更适合您的特定用途。很难说哪个可能更快,因为您没有提到正在读取的文件的任何属性,例如大小、是否包含对齐的数据等。

标签: c++ c linux gcc


【解决方案1】:

如果您按顺序读取文件,我的默认选择是重复 read 到较大的缓冲区中。

如果您要访问分散在大文件周围的少量数据,则选择不太明确,但mmap 可能会导致代码更具可读性(因为您可以像文件已经在内存中一样进行编码) .在这种情况下哪个会提供更好的性能很难先验地判断。

如果您正在编写性能关键代码,那么确定性能的唯一方法是对实际代码进行基准测试/分析。

【讨论】:

  • 事实上,read 绝对不能使用mmap,因为它可以对不可搜索的文件描述符(如管道、tty 或套接字)进行操作。
  • @duskwuff:谢谢。我已经更新了答案以包含您的评论。
  • 这取决于您所指的实施级别。我很确定在 fd 对应的情况下,在幕后 - 也就是说,在内核中 - read 经常使用 mmap (或者更确切地说,系统调用 read 和 mmap 的实现使用相同的底层内存映射机制)到可映射的设备。
  • @evilotto:很好,谢谢。我决定从答案中删除该段落,因为它不会增加太多内容并且会引起不必要的争议。
  • +1 表示“确定性能的唯一方法是对实际代码进行基准测试/分析”。
【解决方案2】:

一般经验法则:

  • 如果您从头到尾按顺序读取文件,则可以使用 read() 而不会影响性能。

  • 如果您正在读取随机访问的文件,则 mmap() 将产生比比较 seek()/read() 组合更好的性能。

【讨论】:

  • @gravitron 说了什么。最快的方法是 fstat 文件找到它的大小,然后在一次 read() 操作中得到它。
  • @PeteWilson:我相信使用 Linux 特定的 MAP_POPULATE 标志映射文件或使用 posix_madvise 会更快。这实质上是将文件缓存映射到您的虚拟 RAM 中,并保存一份副本。
  • @PeteWilson 我同意 Zan 的观点,一旦文件的大小足以要求 VM 保存整个文件,您的建议将受到惩罚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 2018-10-04
  • 2016-02-01
相关资源
最近更新 更多