C++中的有序容器与无序容器

Ordered versus unordered containers in C++

本文关键字:无序 C++      更新时间:2023-10-16

我知道,从算法分析理论的角度来看,在无序容器中进行搜索是恒定的摊销时间复杂度O(1)而在有序容器中,时间复杂度是O(log(n))等。然而,实际上,迫使我们使用无序容器而不是有序容器的定性和定量标准取决于相当多的因素。

哪些

因素决定了使用无序容器比使用其各自的有序容器更具吸引力?

假设您同时具有比较器和哈希函数,因此您可以在两者之间自由选择。还假设您可以避免在一个容器中线性但不能在另一个容器中线性的任何单元素操作(John Zwinck 在评论中提出了一个很好的观点,即无序erase在容器大小上记录为最坏情况下的线性,但实际上实现速度甚至比这慢)。

然后,主要标准是是否需要按排序顺序迭代容器。如果是这样,那么您希望使用订购的容器。如果没有,则您希望使用无序容器。

作为次要可能性,两者的接口非常相似,因此您可以轻松地使用两者测试实际应用程序的性能,并选择更快的接口。按排序顺序迭代无序容器并不是一项困难的编码任务,前提是在您执行此操作时不会对其进行修改。

当然,分析也存在一些陷阱——您的测试可能无法使用实际数据。即使他们没问题,您的用户也可能无法使用实际数据;-)在大多数情况下,没有什么比这更好的了。对于实时保证等特定情况,您需要了解比标准告诉您的更多关于您正在使用的实现的信息(因此,您可能根本不使用标准容器)。

我之所以说在这种情况下性能测试是次要的,只是因为你有无限的开发时间,你可以分析每种可能的不同方法来编写你的程序并选择最好的。由于您没有无限的开发时间,因此您主要选择如何使用启发式方法编写代码。选择了一些有效且大部分并不糟糕的东西后,您可以分析以识别热代码,然后在该代码的看似合理的选项之间进行选择。

赫伯·萨特(Herb Sutter)在他的演讲《现代C++:你需要知道的》中谈到了这一点。https://www.youtube.com/watch?v=TJHgp1ugKGM

总之,使用 std::vector、test 和 profile。 但是 std::vector 通常会以几个数量级的优势获胜。

如果您不需要排序序列,请使用无序容器:它们通常要快得多。当然,这在一定程度上取决于哈希和相等运算符与关系运算符的比较,但假设这些是合理的,您将对无序容器进行更快的操作。像往常一样:您可能应该分析您的特定用例。