【问题标题】:Is using istream::seekg too much expensive?使用 istream::seekg 太贵了吗?
【发布时间】:2014-02-07 15:09:14
【问题描述】:

在 c++ 中,使用 istream::seekg 操作的成本是多少?

编辑:寻找文件和读取字节我能逃脱多少?频率与偏移量的关系如何?

我正在解析一个大文件 (4GB),我想知道是否有必要尝试合并我的一些 seekg 调用。我认为文件位置差异的大小会起作用——比如,如果你在内存中寻找超过一页,它会影响性能——但小的寻找并不重要。这是正确的吗?

【问题讨论】:

  • 位置只是一个指针,改变它并不会真正读取文件内容。
  • 啊,废话。好吧,让我让我的问题更合理......
  • 等等......不,我有充分的理由问这个......
  • 等等,没关系,不,我没有……
  • @jweyrich:没错,你如何访问它很重要。但是来自read 的页面的一个额外副本的成本通常是无关紧要的,特别是如果您随后可以在缓存中对该副本进行操作。 mmap 需要的页表和 TLB 抖动通常最终占主导地位。 (我确实有一种预感,在最近的带有“透明大页”的内核上这可能会有所不同,但我从来没有回去尝试过......)底线是没有什么可以替代基准测试。

标签: c++ large-files ifstream seek seekg


【解决方案1】:

这个问题很大程度上取决于您的操作系统和磁盘子系统。

显然,搜索本身将花费零时间,因为它只是更新一个偏移量。实际上读取会从磁盘中提取一些数据...

...但是有多少数据取决于很多事情。您的磁盘有一个缓存,它可能有自己的块大小,并且可能会进行某种预读。您的 RAID 控制器(如果有)将有自己的缓存,可能有自己的块大小和预读。

你的内核有一个页面缓存——本质上是所有的空闲内存——它也可能会进行某种预读。在 Linux 上这是可配置的,内核会根据您的访问模式的顺序、您是否调用过 posix_fadvise 等来调整它。

所有这些缓存意味着如果您访问一些数据,然后再访问附近的数据,那么第二次访问可能根本不会真正触及磁盘。

如果您可以选择编码以便按顺序访问文件,那肯定会比随机读取更快,尤其是小型随机读取。在单个机械磁盘上​​查找大约需要 10 毫秒,因此您可以在这里进行计算。 (虽然在固态驱动器上搜索要快 100 倍左右。)

大读取通常比小读取好...虽然一次处理几千字节的数据可能比大块更快,如果它允许处理保留在缓存中。

简而言之,您需要提供有关您的系统和应用程序的更多详细信息才能获得正确的答案,即便如此,最有可能的答案是“对其进行基准测试”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    相关资源
    最近更新 更多