这是最快的STL容器查找

Which is the fastest STL container for find?

本文关键字:查找 STL      更新时间:2023-10-16

作为序言,我需要缓存很少修改的数据的一个相对较小的子集,以避免出于性能原因频繁地查询数据库。这个数据在只读意义上被大量使用,因为它经常被其他表中更大的数据集引用。

我已经编写了一个类,它将有能力在内存中存储基本完整的两个表,同时监听提交更改,并结合线程安全回调机制来更新缓存对象。

我当前的实现有两个std::vectors一个用于每个表的元素。该类既提供了对每个向量的完整访问,也提供了通过std::findstd::find_if等查找表数据中特定元素的方便方法。

是否有人知道使用std::list, std::set,或std::mapstd::vector搜索将是可取的?大多数情况下,当建立新的连接时,从数据库中填充一次后,将向这些容器请求此值。

我也愿意使用VS2010或Boost支持的c++ 0x特性。

对于特定值的搜索,std::setstd::map需要O(log N)时间,其他两个需要O(N)时间;因此,std::setstd::map可能更好。由于您可以访问c++ 0x,您也可以使用std::unordered_setstd::unordered_map,它们平均花费常数时间。

对于find_if,它们之间几乎没有区别,因为它使用任意谓词,容器当然不能任意优化。

但是,如果您将使用特定谓词频繁调用find_if,您可以优化自己:使用带有自定义比较器或特殊键的std::mapstd::set,并使用find代替。

如果你不经常更新,使用std::lower_bound的排序向量可以和std::set一样快;它们都是O(log n)值得两种方法都试一下看看哪个更适合你自己的情况

因为从您的(扩展)需求,您需要搜索多个字段,我会指出您的Boost.MultiIndex.

这个Boost库允许您构建一个容器(它所包含的每个元素只有一个示例),并在上索引任意数量的索引。它还可以让您精确地使用哪些索引。

要确定要使用的索引类型,需要进行大量的基准测试。500是相对较低的条目数,所以常数因子不能很好地发挥作用。此外,单线程和多线程使用之间可能存在明显的差异(大多数哈希表实现在MT使用上可能会崩溃,因为它们不使用线性重新哈希,因此单个线程最终会重新哈希表,阻塞所有其他线程)。

如果性能差异不明显或根本无关紧要,我建议使用排序索引(跳跃式索引,如果可能的话)来适应范围请求(所有名称以Abc开头)。

如果您只想搜索不同的值,表中的一个特定列,那么std::hash是最快的。

如果您希望能够使用多个不同的谓词进行搜索,则需要某种索引结构。它可以通过扩展当前基于向量的方法来实现,使用多个哈希表或映射,每个字段一个用于搜索,其中值要么是指向向量的索引,要么是指向向量中元素的直接指针。

更进一步,如果您希望能够搜索范围,例如所有在7月有日期的场合,您需要一个有序的数据结构,可以从中提取范围。

本身不是答案,但一定要使用typedef来引用您使用的容器类型,例如typedef std::vector< itemtype > data_table_cache;,然后在任何地方使用您的typedef类型。