有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
What are some efficient ways to de-dupe a set of > 1 million strings?
对于我的项目,我需要非常有效地对非常大的字符串集进行重复数据消除。 即,给定一个可能包含重复项的字符串列表,我想生成该列表中所有字符串的列表,但没有任何重复项。
下面是简化的伪代码:
set = # empty set
deduped = []
for string in strings:
if !set.contains(string):
set.add(string)
deduped.add(string)
这是它的简化C++(大致(:
std::unordered_set <const char *>set;
for (auto &string : strings) {
// do some non-trivial work here that is difficult to parallelize
auto result = set.try_emplace(string);
}
// afterwards, iterate over set and dump strings into vector
但是,这对于我的需求来说还不够快(我已经仔细地对其进行了基准测试(。以下是一些使其更快的想法:
- 使用不同的C++集实现(例如,绳降的(
- 并发插入到集合中(但是,根据C++实现中的注释,这很难。此外,并行化会有性能开销(
- 由于字符串集在运行中变化很小,因此无论哈希函数是否不生成冲突,都可以缓存。如果它没有生成任何内容(在考虑更改时(,则可以在查找期间通过其哈希值来比较字符串,而不是实际的字符串相等性(
strcmp
(。 - 在运行过程中将去重复的字符串存储在文件中(但是,尽管这看起来很简单,但这里有很多复杂性(
我发现,所有这些解决方案要么非常棘手,要么没有提供那么大的加速。快速重复数据删除有什么想法吗?理想情况下,不需要并行化或文件缓存的东西。
您可以尝试各种算法和数据结构来解决问题:
- 尝试使用前缀树(trie(,后缀机器,哈希表。哈希表是查找重复项的最快方法之一。尝试不同的哈希表。
- 使用各种数据属性来减少不必要的计算。例如,只能处理具有相同长度的字符串子集。
- 尝试实现"分而治之"方法来并行计算。例如,将字符串集除以等于硬件线程的子集数。然后将这些子集合并为一个。由于子集的大小将在此过程中减小(如果重复项的数量足够大(,因此组合这些子集应该不会太昂贵。
不幸的是,这个问题没有通用的方法。在很大程度上,决策取决于所处理数据的性质。在我看来,我清单上的第二项是最有希望的。始终尝试减少计算以使用较小的数据集。
您可以通过手动实现简化版本的std::unordered_set
来显著并行化您的任务:
- 创建任意数量的存储桶(可能应与线程池中的线程数成比例或等于(。
- 使用线程池并行计算字符串的哈希值,并用它们的哈希值拆分字符串。添加字符串时,您可能需要锁定单个存储桶,但操作应简短和/或您可以使用无锁结构。
- 使用线程池单独处理每个存储桶 - 比较哈希值,如果它们相等,则比较字符串本身。
您可能需要试验存储桶大小并检查它会如何影响性能。从逻辑上讲,它不应该在一侧太大,但在另一侧不应该太小 - 以防止拥堵。
顺便说一句,从您的描述中可以看出,您将所有字符串加载到内存中,然后消除重复项。您可以尝试将数据直接读取到std::unordered_set
,这样您就可以节省内存并提高速度。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 两个字符串在 c++ 中不相等
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 构造<int>具有 2 个字符串文字的向量
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 当我读取一个大小为 17 mb 的 100 万个 url 文件时,我的程序占用大小为 163 MB
- 比较推送数据(100 万个数字)在 std::vector 中预先调整大小和没有
- 向量在 2500 万个向量中的查找距离
- 如何输出字符串第二个单词的第一个字母?
- C++ 100 万个变量名称的最小和最大变量名称长度是多少
- 在C++中,有没有获得字符串第一个字符的最佳实践
- 如何提高具有100万个元素和997个存储桶的哈希表的性能
- 测量在算法库中对100万个0到1之间的浮点数进行排序的时间
- 创建一个包含300万个元素的双数组
- 将固定长度的短字符串(52个字符)压缩到小于40个
- 用这种方式比较字符串是个好方法吗
- 为什么我不能在 STL 集中插入 600 万个元素?
- STL C++队列中的300万个元素
- 如何通过 bash shell 输入 c++ 字符串 >= 1024 个字符?