哪个是查找最快的STL容器?

时间:2011-08-08 16:49:32

标签: c++ optimization stl find

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

我编写了一个类,它能够在内存中基本上存储两个表的全部内容,同时监听提交更改以及用于更新缓存对象的线程安全回调机制。

我当前的实现有两个std::vectors一个用于每个表的元素。该类提供对每个向量的全部访问权限以及通过std::findstd::find_if等搜索表数据的特定元素的便捷方法。

是否有人知道使用std::liststd::setstd::map而不是std::vector进行搜索会更好?大部分时间是在建立新连接后从数据库填充一次后将要求这些容器。

我也愿意使用VS2010或Boost支持的C ++ 0x功能。

7 个答案:

答案 0 :(得分:53)

对于搜索特定值,使用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使用自定义比较器或特殊键并使用{{1相反。

答案 1 :(得分:21)

如果您不经常更新,使用std::lower_bound的排序向量可能与std::set一样快;他们都是O(log n)。值得一试,看看哪种情况对你自己的情况有好处。

答案 2 :(得分:3)

由于你的(扩展)需求需要搜索多个字段,我会指向Boost.MultiIndex。

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

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

我会推荐一个排序索引(跳过列表,如果可能的话)来容纳范围请求(所有名称以Abc开头?)如果性能差异不明显或根本无关紧要。

答案 3 :(得分:2)

测试一下。 这很简单,容器在STL中几乎可以互换。

答案 4 :(得分:2)

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

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

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

答案 5 :(得分:0)

不是stl,但商业c ++容器是abax容器,在插入中有O(1)搜索,删除,修改,O(logn)。

答案 6 :(得分:-1)

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