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

C++ 查找最快的STL容器是哪个?,c++,optimization,stl,find,C++,Optimization,Stl,Find,好的,作为前言,我需要缓存很少修改的数据的相对较小的子集,以避免出于性能原因频繁地查询数据库。此数据在只读意义上被大量使用,因为它经常被其他表中更大的数据集引用 我已经编写了一个类,它能够在侦听提交更改的同时,将两个表的全部内容存储在内存中,并使用线程安全回调机制来更新缓存对象 我当前的实现有两个std::vectors每个表的元素一个。该类提供了对每个向量整体的访问,以及通过std::find,std::find_if等搜索表数据特定元素的方便方法 有人知道使用std::list、std::s

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

我已经编写了一个类,它能够在侦听提交更改的同时,将两个表的全部内容存储在内存中,并使用线程安全回调机制来更新缓存对象

我当前的实现有两个
std::vectors
每个表的元素一个。该类提供了对每个向量整体的访问,以及通过
std::find
std::find_if
等搜索表数据特定元素的方便方法

有人知道使用
std::list
std::set
std::map
进行搜索是否更可取吗?在大多数情况下,当建立新连接时,从数据库中填充一次后,将请求这些容器


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

用于搜索特定值,使用
std::set
std::map
需要O(logn)时间,而使用其他两个则需要O(N)时间;因此,
std::set
std::map
可能更好。由于您可以访问C++0x,因此还可以使用
std::unordered_set
std::unordered_map
,它们平均花费恒定的时间

对于
find_if
,它们之间没有什么区别,因为它需要一个任意谓词,当然容器不能任意优化


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

如果您只想搜索不同的值,请在表中指定一列,然后
std::hash
是最快的

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


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

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

因为根据你(扩展)的要求,你需要在多个字段上搜索,我建议你使用Boost.MultiIndex

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

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


如果性能差异不明显或根本不重要,我建议使用排序索引(如有可能,跳过列表)来容纳范围请求(所有名称以Abc开头)。

本身不是答案,但一定要使用typedef来引用您使用的容器类型,类似于
typedef std::vectordata\u table\u cache然后在任何地方使用typedef类型

即使没有C++0x,您也可以在TR1中查找无序容器,即
#include
std::TR1::unordered_map
。不过,您确实需要进行测试,因为渐近线(O(1)vs O(logn))不会告诉您常数的大小,而且n可能必须是泰坦尼克号,才能使无序容器更有效!是的,测试很重要!如果不是大量数据,“较慢”的容器可能工作得更好。当使用无序向量时,哈希函数的质量也会有所不同。几乎所有情况下,向量的组合大小都将小于500个元素。它们仅在组织上是分开的。我需要能够使用lambdas搜索name字段和id字段,从而搜索谓词和
std::find_if
。我需要对一组大约100万个值进行大约100多万次的查找。使用无序的_集执行所有查找大约需要7秒钟。使用向量法花了30多分钟(找到这个答案后我停止了)。这就是为什么我爱你!谢谢R.Martinho Fernandes!我没有提到我需要在多个值上查找,这些值需要按名称或id重新排序。这是到目前为止对实际问题的最佳答案。根据我的经验,排序的向量明显比集合快(而且内存占用更少);明显的权衡是修改存储的数据代价高昂。如果您需要按不同的字段查找,最简单的解决方案是为每个字段使用不同的排序向量(可能是指针向量,以避免重复一组信息),那么typedef除了尽可能减少键入之外还有什么区别?模板实例化在编译时解析,我使用C++0x