【问题标题】:What's the fastest way to read a file from start to finish?从头到尾读取文件的最快方法是什么?
【发布时间】:2020-09-23 15:55:26
【问题描述】:

我通过分析器运行我的代码,发现大部分时间 (60%) 都花在了读取文件上。运行只需要几毫秒,但我想知道我是否可以让它更快。我的代码有 20 个文件的列表(从 1k 到 1M)。它打开一个,将整个文件读入 ram,处理它(顺序,读取所有内容一次),然后重复打开/读取/处理/关闭其余文件重用同一个缓冲区

我想知道是否有办法让任何事情变得更快?我尝试将 posix_fadvise 与 POSIX_FADV_SEQUENTIAL 和 POSIX_FADV_WILLNEED 一起使用,使用文件偏移量 len 作为0, 00, st_size。这似乎没有什么不同。在阅读之前,我还没有编写代码来打开所有文件。那会有什么不同吗?我应该对所有这些都使用 posix_fadvise 吗?我应该使用 POSIX_FADV_SEQUENTIAL 还是 POSIX_FADV_WILLNEED?

【问题讨论】:

  • 文件 IO 是一个常见的瓶颈。听起来您无能为力。
  • 如果只有20M,把文件放到ramdisk上。或者使用 SSD。
  • 如果不显示任何代码,很难看出如何优化您的代码。你想让我们猜吗?或者,您希望我们在所有可能的情况下为您提供最佳解决方案,而无需了解您的环境、架构、编译器或您是否有兴趣回答您的问题?

标签: c linux file


【解决方案1】:

fadvise 只有在以下情况下才真正有帮助:

  1. 它是在您开始阅读之前发布的,或者
  2. 您正在零碎地读取文件(理想情况下,读取之间存在一些处理间隙)。

如果您只是在打开文件后立即将整个文件放入 RAM 中,则没有太多需要优化的地方;该文件必须从头到尾读取,并且您没有给操作系统足够的警告来缓存它。需要考虑的事项:

  1. 打开和fadviseing 文件 n+1 就在之前您开始从文件 n 读取(因此操作系统在您处理当前文件时缓存下一个文件)
  2. 使用mmap+madvise(WILLNEED) 避免在开始处理之前将文件从内核一次全部复制到用户缓冲区;如果文件的处理成本足够高,则可能会在您处理完文件中的早期页面时读入后续页面。

鉴于这些是小文件,我会坚持使用WILLNEEDSEQUENTIAL 扩大了预读缓冲区,但无论如何你都会读取整个文件(可能是批量读取,SEQUENTIAL 没有多大帮助)所以你最好尽快缓存整个文件.

【讨论】:

  • 谢谢。几天后我会接受,因为我可以更好地衡量它并确认它有效
【解决方案2】:

在我看来,这段代码摘自“C 编程语言”的第一版,它很难被超越:

#include <stdio.h>
main()
{
    int c;
    while((c = getchar()) != EOF)
        putchar(c);
}

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 2013-01-17
    相关资源
    最近更新 更多