首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析mmap()-ed文件

解析mmap()-ed文件
EN

Stack Overflow用户
提问于 2011-03-01 19:31:24
回答 5查看 1.3K关注 0票数 1

解析mmap文件的最佳(最快)方法是什么?它包含成对的数据(字符串int),但我不能在它们之间添加空格/制表符/换行符的数量。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-01 20:00:07

假设您已经将整个文件(而不是块-因为这将使生活变得非常复杂)进行了mmaped,我将执行类似以下的操作...

代码语言:javascript
复制
// Effectively this wraps the mmaped block
std::istringstream str;
str.rdbuf()->pubsetbuf(<pointer to start of mmaped block>, <size of mmaped block>);

std::string sv;
std::string iv;

while(str >> sv >> iv)
{
  // do stuff...
}

我想这应该行得通。

警告这是实现定义的行为,有关更好的方法,请参阅this answer

票数 3
EN

Stack Overflow用户

发布于 2011-03-01 19:47:39

如果您所说的最好/最快是指最容易编码,那么这是少数几种情况下,不推荐使用的std::istrstream完全符合要求;调用istrstream::istrstream(char const*, std::streamsize)构造函数重载,然后像从任何其他std::istream中一样从流中提取数据。(这不会像std::istringstream那样复制底层内存。)

如果你所说的最佳/最快是指最佳/最快的运行时性能,我认为你无法胜过boost.spirit.qi或手写解析器,尽管在我看来,前者更容易编写和维护(如果你以前从未使用过boost.spirit,那么库学习曲线暂且不提)。

票数 2
EN

Stack Overflow用户

发布于 2011-03-01 21:05:29

解析由空格分隔的字符串/整数对(例如foo 50 bar 20 baz 123)无论哪种方式都应该非常快。到目前为止更重要的因素是

a)页面实际上在RAM中,mmap本身不能保证

b)高速缓存线在L1高速缓存中

虽然mmap在默认情况下已经在顺序访问上进行了预读,但磁盘访问是在几十毫秒内进行的,而对4k内存页面的解析(理想情况下)是在几十微秒内进行的。

因此,您不能期望预取器跟上进度,特别是因为它只在您需要更多预取时才进行预取(即使假设寻道时间为零,实际上也保证了由于机械磁盘上的旋转延迟而产生的前期成本)。

因此,除非您的总数据只有12 as (在这种情况下,关于如何尽可能快地完成扫描的问题将是毫无意义的),否则在开始扫描之前使用case (MADV_WILLNEED)是有意义的,这样操作系统就不会等待看到您的访问模式触发它的启发式,而是不间断地按顺序读取它可以读取的内容。磁盘带宽(按顺序),一旦超过访问时间,就会非常大。你可能还会赶上,但是很久以后。如果您的数据集足够大,可能无法放入内存中,那么对您经常看到的数据调用MADV_DONTNEED是一个好主意。

对于页错误也是如此,对于高速缓存未命中也是如此。从缓存加载是1-2个周期,从内存加载大约是200-500个周期。

CPU具有针对顺序访问模式的自动预取,但它们是有限的。

首先,预取永远不会跨越页面边界发生。这是因为如果是这种情况,那么自动预取将定期触发页面错误,这将是非常令人不快的。

其次,预取只有在连续两次未命中之后才会发生,这是为了确保预取只在可能有意义的时候才开始。为每个随机读取预取相邻的高速缓存线将是愚蠢的,因为它将不必要地丢弃有价值的高速缓存线。

第三,预取需要时间,一旦CPU中的启发式触发,您就已经在与它竞争数据,所以越快越好。

幸运的是,你知道你将需要什么数据,而且你很久以前就知道了。因此,您可以给出预取提示,这将为CPU提供有价值的领先优势(例如,提前半千字节预取)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5153908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档