【发布时间】:2011-07-07 01:52:32
【问题描述】:
在进行一些测量后,这里有一段代码是一个相当大的瓶颈:
//-----------------------------------------------------------------------------
// Construct dictionary hash set from dictionary file
//-----------------------------------------------------------------------------
void constructDictionary(unordered_set<string> &dict)
{
ifstream wordListFile;
wordListFile.open("dictionary.txt");
std::string word;
while( wordListFile >> word )
{
if( !word.empty() )
{
dict.insert(word);
}
}
wordListFile.close();
}
我正在阅读大约 200,000 个单词,这在我的机器上大约需要 240 毫秒。这里使用ifstream高效吗?我能做得更好吗?我正在阅读有关 mmap() 实现的信息,但我并没有 100% 理解它们。输入文件只是带有 *nix 行终止的文本字符串。
编辑:后续问题建议的替代方案: any 替代方案(减去增加流缓冲区大小)是否意味着我编写了一个解析器来检查每个字符的换行符?我有点喜欢流的简单语法,但如果我必须为了速度,我可以重写一些更具体的东西。将整个文件读入内存是一个可行的选择,它只有大约 2mb。
编辑#2:我发现我的速度变慢是由于设置插入,但是对于那些仍然对逐行加速文件 IO 感兴趣的人,请阅读在这里回答并查看Matthieu M.'s continuation on the topic.
【问题讨论】:
-
关于读取的最大收获是使用大缓冲区,这样您就不必为每一行(或小缓冲区)遍历所有 O/S 层,也不会重复支付性能开销罚款。不知道增加 ifstream 的读取缓冲区大小的 API 是什么,这就是为什么这是评论,而不是答案。但我确信有一种方法可以调整缓冲区的大小(或分配你自己的,指定它的大小)。
-
当性能出现问题时,您应该做的第一件事是profile。看看你的代码大部分时间都花在了哪里。据我们所知,这可能是在将值添加到您的字典中。不太可能,我知道,但如果你需要性能,你真的需要知道。
-
@sbi:这不太可能。在高性能统计应用程序中,我发现
unordered_map的 Boost 版本比 Google 的sparsehash慢一个数量级,并且比 GNUstd::map快不了多少。 -
@sbi 和@larsmans:你们是对的,请参阅已接受的答案。
标签: c++ optimization file-io ifstream