作为前言,我需要缓存很少修改数据的相对较小的子集,以避免出于性能原因频繁查询数据库。这些数据大量用于只读意义,因为它通常由其他表中更大的数据集引用。
我编写了一个类,它能够在内存中基本上存储两个表的全部内容,同时监听提交更改以及用于更新缓存对象的线程安全回调机制。
我当前的实现有两个std::vectors
一个用于每个表的元素。该类提供对每个向量的全部访问权限以及通过std::find
,std::find_if
等搜索表数据的特定元素的便捷方法。
是否有人知道使用std::list
,std::set
或std::map
而不是std::vector
进行搜索会更好?大部分时间是在建立新连接后从数据库填充一次后将要求这些容器。
我也愿意使用VS2010或Boost支持的C ++ 0x功能。
答案 0 :(得分:53)
对于搜索特定值,使用std::set
和std::map
需要O(log N)时间,而其他两个则需要O(N)时间;因此,std::set
或std::map
可能更好。由于您可以访问C ++ 0x,因此您还可以使用std::unordered_set
或std::unordered_map
,这会花费平均时间。
对于find_if
,它们之间没有什么区别,因为它需要一个任意谓词,当然容器也不能随意优化。
但是,如果您经常使用某个谓词调用find_if
,则可以自行优化:使用std::map
或std::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类型。