C++中的有序容器与无序容器
Ordered versus unordered containers in C++
我知道,从算法分析理论的角度来看,在无序容器中进行搜索是恒定的摊销时间复杂度O(1)
而在有序容器中,时间复杂度是O(log(n))
等。然而,实际上,迫使我们使用无序容器而不是有序容器的定性和定量标准取决于相当多的因素。
因素决定了使用无序容器比使用其各自的有序容器更具吸引力?
假设您同时具有比较器和哈希函数,因此您可以在两者之间自由选择。还假设您可以避免在一个容器中线性但不能在另一个容器中线性的任何单元素操作(John Zwinck 在评论中提出了一个很好的观点,即无序erase
在容器大小上记录为最坏情况下的线性,但实际上实现速度甚至比这慢)。
然后,主要标准是是否需要按排序顺序迭代容器。如果是这样,那么您希望使用订购的容器。如果没有,则您希望使用无序容器。
作为次要可能性,两者的接口非常相似,因此您可以轻松地使用两者测试实际应用程序的性能,并选择更快的接口。按排序顺序迭代无序容器并不是一项困难的编码任务,前提是在您执行此操作时不会对其进行修改。
当然,分析也存在一些陷阱——您的测试可能无法使用实际数据。即使他们没问题,您的用户也可能无法使用实际数据;-)在大多数情况下,没有什么比这更好的了。对于实时保证等特定情况,您需要了解比标准告诉您的更多关于您正在使用的实现的信息(因此,您可能根本不使用标准容器)。
我之所以说在这种情况下性能测试是次要的,只是因为你有无限的开发时间,你可以分析每种可能的不同方法来编写你的程序并选择最好的。由于您没有无限的开发时间,因此您主要选择如何使用启发式方法编写代码。选择了一些有效且大部分并不糟糕的东西后,您可以分析以识别热代码,然后在该代码的看似合理的选项之间进行选择。
赫伯·萨特(Herb Sutter)在他的演讲《现代C++:你需要知道的》中谈到了这一点。https://www.youtube.com/watch?v=TJHgp1ugKGM
总之,使用 std::vector、test 和 profile。 但是 std::vector 通常会以几个数量级的优势获胜。
如果您不需要排序序列,请使用无序容器:它们通常要快得多。当然,这在一定程度上取决于哈希和相等运算符与关系运算符的比较,但假设这些是合理的,您将对无序容器进行更快的操作。像往常一样:您可能应该分析您的特定用例。
- 递归无序映射
- c++找不到具有相同哈希的无序集合元素
- 正在将无序映射设置为无序映射的值
- 智能指针作为无序映射键,并通过引用进行比较
- 如何使用set实现无序数据结构?
- 如何写向量的无序向量集,即unordered_set<向量<向量<int>>集合?
- 如何禁用 CPU 的无序执行
- 从C++无序集合中高效提取元素
- 打印无序映射的第二个元素,即集合
- 当我将其插入无序地图时,矢量的容量为 0
- 代码块中无序多集的编译错误17.12
- 由并发无序映射查找线程调用的函数是否安全?
- 如何按值对无序哈希映射进行排序
- gtest 期望无序元素与自定义比较器/匹配器一起使用
- 将大数字(10-12 位数字)存储在无序映射中<字符串,整数>
- 使用无序映射在STL中存储键值对
- 为C++中的无序映射获取给定输入键的错误值
- 如何将一个单词拆分成字母,并将它们放入一个无序的列表/集合中
- 将大型对象存储在无序映射中是否效率低下
- 仅从无序集合中删除一个项目