使用 istream::seekg 会很昂贵吗?

10

在c++中,使用istream::seekg操作会有多大的代价?

编辑:我可以在文件中进行多少次寻址和读取字节?偏移量的频率和大小有什么区别吗?

我有一个大文件(4GB),我正在解析它,我想知道是否有必要尝试合并我的seekg调用。我认为文件位置的差异程度会起到一定作用 - 比如说如果您跳过了内存中的一页以上,那么它将影响性能 - 但小的寻址则无关紧要。这个理解正确吗?


2
这个位置只是一个指针,改变它并不会实际读取文件内容。 - WiSaGaN
啊,糟糕。好吧,让我把我的问题说得更加合理一些... - Brian
等一下...不,我问这个问题是有充分理由的。 - Brian
等等,算了,我没有这样做。 - Brian
2
@jweyrich:确实,访问它的方式很重要。但是从read中多复制一页的成本通常是无关紧要的,特别是如果您可以在缓存中操作该副本。 mmap需要的页表和TLB抖动经常会占主导地位。(我确实有一种预感,最近的内核可能会有所不同,具有“透明大页面”,但我从未回去尝试过...)底线是没有什么可以替代基准测试。 - Nemo
显示剩余8条评论
1个回答

9
这个问题与您的操作系统和磁盘子系统密切相关。显然,搜索本身将需要零时间,因为它只更新偏移量。实际读取将从磁盘中提取一些数据...但是要提取多少数据取决于许多因素。您的磁盘具有缓存,可能具有自己的块大小,并且可能会进行某种读取前导。您的RAID控制器(如果有)将具有其自己的缓存,可能具有自己的块大小和预读功能。您的内核具有页面缓存 - 基本上是所有可用的RAM - 并且它还可能进行某种阅读前导。在Linux上,这是可配置的,并且内核将根据您的访问模式的顺序性,是否调用了posix_fadvise等来进行适应。
所有这些缓存意味着如果您访问一些数据,然后稍后访问附近的数据,则第二次访问可能根本不会接触到磁盘。
如果您可以编写代码以使文件连续访问,那肯定比随机读取更快,特别是对于小的随机读取。在单个机械磁盘上执行搜索大约需要10毫秒左右,所以您可以在这里计算一下。(虽然在固态驱动器上搜索大约快100倍。)
大读取通常比小读取更好...尽管如果允许处理保持在缓存中,以每次几千字节的数据处理可能比较大的块更快。
简而言之,您需要提供有关系统和应用程序的更多详细信息才能获得正确的答案,即使是这样,最有可能的答案仍然是“进行基准测试”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接