【发布时间】:2019-08-08 17:40:56
【问题描述】:
我有 4e7 std::strings,每个大约 3 到 30 个字符长,有很多重复。
我将它们放入std::set。
为每个字符串调用set::insert 会变得非常缓慢,直到它完成大约 1e7 个唯一字符串。所以instead我把push_back的每个字符串变成了vector、sort()和unique()那个,然后把move的字符串变成了set。
它仍然很慢,但至少它完成了:累积向量需要 4 秒,sort() 多 30 秒,unique() 多 3 秒。
瓶颈是sort()。 但我不需要按字典顺序对字符串进行排序!我只需要重复的字符串是连续的,对于unique()。他们的顺序无关紧要。
sort() 是否有一个更简单、更快的字符串比较函数,我可以使用它来代替它的默认函数?
或者我应该通过在侧面使用哈希表迭代向量来更快地构建集合,以跳过重复项?或者将set替换为hash_set或unordered_set?
编辑:我正在使用 g++ 4.8.4 在 Linux 上构建,唯一的标志是 -std=c++11 -O3。
【问题讨论】:
-
我绝对建议您使用
std::unordered_set进行测量。 -
这篇博客 (?) 帖子对请求的算法进行了一些讨论:lemire.me/blog/2008/05/01/…
-
@CamilleGoudeseune 我没有看到您如何构建您正在测试的应用程序。您是在运行优化的构建,还是“调试”的非优化构建?
-
如果你知道你的字符串永远不会超过 30 个字符,你可以尝试用例如替换
std::stringchar[32]或类似的东西。避免堆分配可以显着提高速度。