具有最快“存在”搜索的 C++ 容器(向量/数组/等)
Posted
技术标签:
【中文标题】具有最快“存在”搜索的 C++ 容器(向量/数组/等)【英文标题】:C++ Container with Fastest "Exists" Seeking (Vector/Array/etc) 【发布时间】:2014-03-20 14:50:18 【问题描述】:我不确定在这里使用的最佳 C++ 数据容器......我正在构建一个对延迟非常敏感的应用程序(因此我需要绝对最快的实现)。
我需要一次性存储大约 300,000 个字符串(仅一次写入),然后经常检查该数据存储中是否存在某个元素(多次读取)。除了检查其中是否存在值外,我不需要对这个数据集做任何其他事情,而且我需要每秒检查数百次。如果这很重要,大多数查找将导致找不到密钥。
我考虑过使用向量或数组,但它们似乎都只是简单地扫描整个列表并一对一地检查值......这会起作用......但是因为我们正在索引字符串,所以没有任何数据容器为值构建某种树索引,因此在搜索值“apple”时,它会首先查看以“a”开头的键,然后是下一个字符“p”,以及何时它没有找到任何“ap ...”它立即返回未找到。对我来说,这似乎比每次搜索整个庞大的集合要快。我真的希望原生容器具有这种功能。
如果有帮助的话,这个项目确实已经编译了 Boost。
非常感谢!
【问题讨论】:
std::set
和 std::map
构建红黑树。 std::unordered_set
和 std::unordered_map
是哈希表。
@MichałGóral C++ 没有指定树的具体类型。
【参考方案1】:
有了 Boost,答案显然是 boost::unordered_set
。
它也可以作为 C++11 中标准的一部分作为 std::unordered_set
在 <unordered_set>
中使用。
它们都建立在哈希表上,因此计算哈希后查找本身的 O(1)。
【讨论】:
请原谅我的无知,但假设unordered_set
哈希表比普通set
中的红黑树更快,以进行简单的“如果存在”查找?
这是平均 O(1) 查找,在最坏的情况下是线性的,而 std::set 总是 O(log(N))
完美,因为我不相信有比 O(1) 更好的方法,unordered_set
是。谢谢!
@Harry,并不是保证会更快,但对于大型数据集,可能会更快。如果这很重要,您应该真正为自己进行基准测试。【参考方案2】:
那个树容器叫做Trie
Here你可以找到Boost.Trie,我没用过,不知道有没有完成。
【讨论】:
这听起来很有趣,这就是我所描述的,但对于我的速度要求来说可能有点过多的开销。 Trie 应该会表现得更好,尤其是在有很多未命中的情况下。【参考方案3】:这取决于您是否可以将数据保存在内存中,而不是用于该目的的最佳容器是 unordered_set。如果您需要检查集合中是否存在某个键,它具有 O(1) 访问时间。 Boost 提供了很好的实现,你可以在这里找到http://www.boost.org/doc/libs/1_55_0/doc/html/unordered.html。
如果由于数据太大而无法将数据保存在内存中,则可以使用不同的技巧。您可以计算每个字符串的一些小哈希(您可以找到不同的哈希函数),因此它基本上就像从 string -> int 转换一样。然后,每当您需要测试数据库中是否存在字符串时,您只需将其转换为 int (使用相同的哈希函数)并检查哈希表是否存在。如果您需要检索数据,您可以将哈希值与文件中字符串的偏移量相关联,但在您的情况下,您可以考虑仅在需要节省空间时才保留哈希值。
PS。 unordered_set 也使用了哈希函数,只是被隐藏了。
【讨论】:
以上是关于具有最快“存在”搜索的 C++ 容器(向量/数组/等)的主要内容,如果未能解决你的问题,请参考以下文章