【问题标题】:faster string comparison for sorting, for unique()用于排序的更快的字符串比较,用于 unique()
【发布时间】:2019-08-08 17:40:56
【问题描述】:

我有 4e7 std::strings,每个大约 3 到 30 个字符长,有很多重复。 我将它们放入std::set

为每个字符串调用set::insert 会变得非常缓慢,直到它完成大约 1e7 个唯一字符串。所以instead我把push_back的每个字符串变成了vectorsort()unique()那个,然后把move的字符串变成了set

它仍然很慢,但至少它完成了:累积向量需要 4 秒,sort() 多 30 秒,unique() 多 3 秒。

瓶颈是sort()但我不需要按字典顺序对字符串进行排序!我只需要重复的字符串是连续的,对于unique()。他们的顺序无关紧要。 sort() 是否有一个更简单、更快的字符串比较函数,我可以使用它来代替它的默认函数?

或者我应该通过在侧面使用哈希表迭代向量来更快地构建集合,以跳过重复项?或者将set替换为hash_setunordered_set

编辑:我正在使用 g++ 4.8.4 在 Linux 上构建,唯一的标志是 -std=c++11 -O3

【问题讨论】:

  • 我绝对建议您使用std::unordered_set 进行测量。
  • 相关,可能重复:stackoverflow.com/q/14023106/1896169
  • 这篇博客 (?) 帖子对请求的算法进行了一些讨论:lemire.me/blog/2008/05/01/…
  • @CamilleGoudeseune 我没有看到您如何构建您正在测试的应用程序。您是在运行优化的构建,还是“调试”的非优化构建?
  • 如果你知道你的字符串永远不会超过 30 个字符,你可以尝试用例如替换 std::string char[32] 或类似的东西。避免堆分配可以显着提高速度。

标签: c++ sorting c++11 unique


【解决方案1】:

@Someprogrammerdude、@J.AntonioPerez、@KennyOstrom:std::unordered_set 快了 6 倍。发表答案,我会接受。 (在所有这些 cmets 中,此优惠可能已丢失。)

vector<string> v;
loop { v.push_back(my_string[i]; }

慢原创:

sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
set<string> noduplicates = set<string>(
  make_move_iterator(v.begin()), make_move_iterator(v.end()));

比前面的代码块快 6 倍:

unordered_set<string> noduplicates =
  unordered_set<string>(
  make_move_iterator(v.begin()), make_move_iterator(v.end()));

【讨论】:

  • 您可以接受自己的答案。它仍然是一个有效的答案,并且您已经完成了测试。
  • 比 sorted_set 快 6 倍还是比 sort+unique 快 6 倍?
  • 比sort+erase+unique+move,即前面的代码块。
猜你喜欢
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多