【问题标题】:High performance reading - linux/pthreads高性能读取 - linux/pthreads
【发布时间】:2011-12-07 12:28:01
【问题描述】:

我有一个中等大小的二进制文件,由这样的独立块组成:

标题1 数据1 标头2 数据2 标题3 数据3 ...

块的数量、每个块的大小和文件的总大小变化很大,但典型的数字是 ~1000 个块,平均块大小为 100kb。这些文件是由我无法控制的外部应用程序生成的,但我想尽快阅读它们。在许多情况下,我只对一小部分(即 10 %)块感兴趣,我将针对这种情况进行优化。

我目前的实现是这样的:

  1. 打开文件并读取所有标题 - 使用标题中的信息 fseek() 到下一个标题位置;保留一个打开的 FILE * 指针。
  2. 当请求数据时,使用 fseek() 定位数据块,读取所有数据并返回。

这很好用 - 但我在想也许(?)可以使用例如加快速度。 aio、mmap 或其他我只听说过的技术。

有什么想法吗?

乔金

【问题讨论】:

    标签: c linux


    【解决方案1】:

    mmap 和 read 的速度差别不大(都需要从磁盘读取数据),mmap 最大的优点是避免了双缓冲。

    如果您只对 10% 的内容感兴趣,那么您最大的节省将是阅读其他 90%。这可以通过仅读取标头并寻找下一个标头或想要的数据块来完成。但这一切都取决于文件格式,OP没有详细显示。

    【讨论】:

      【解决方案2】:

      大部分时间可能都花在了访问磁盘上。因此,也许购买 SSD 是明智的。 (无论您做什么,您的应用程序都受 I/O 限制)。

      显然,您的文件只有大约 100Mb。您可以通过读取它在磁盘(内核文件)缓存中获取它,例如在运行程序之前使用cat yourfile > /dev/null。对于这么小的文件(在合理的机器上它可以放入 RAM),我不会那么担心。

      您可以预处理文本文件,例如创建一个数据库(用于sqlite,或像 PostGreSQL 这样的真正 RDBMS)或只是一个 gdbm 索引文件。

      如果使用<stdio.h>,您可能会使用setbuffer 获得更大的缓冲区,或者使用"rmt" 模式调用fopenm 是一个 GNU Glibc 扩展来询问 mmap-ing 它)。

      您可以将mmapmadvise 一起使用。

      您可以(也许在单独的线程中)使用readahead 系统调用。

      但是您的文件似乎足够小,您不应该打扰那么多。你确定这真的是一个性能问题吗?您是每天阅读该文件数千次,还是拥有数百个此类文件?

      【讨论】:

      • 谢谢 - 我将研究 mmap + madvise 和我不知道的预读系统调用;但你是对的 - 也许性能已经足够好了。
      • 先试试cat的把戏...你会感到惊讶...但我真的觉得你太担心了...
      猜你喜欢
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      • 2011-09-26
      • 1970-01-01
      • 2019-04-05
      • 2015-05-21
      相关资源
      最近更新 更多