简体   繁体   English

STL向量与列表:图形邻接列表最有效吗?

[英]STL vector vs list: Most efficient for graph adjacency lists?

Lists consume most of their time in allocating memory when pushing_back. 在push_back时,列表占用大部分时间来分配内存。 On the other hand, vectors have to copy their elements when a resize is needed. 另一方面,当需要调整大小时,向量必须复制它们的元素。 Which container is, therefore, the most efficient for storing an adjacency list? 因此,哪个容器最适合存储邻接列表?

I don't think this can be answered with absolute certainty. 我不认为这可以绝对肯定地回答。 Nonetheless, I'd estimate that there's at least a 90% chance that a vector will do better. 尽管如此,我估计一个载体至少有90%的可能性会更好。 An adjacency list actually tends to favor a vector more than many applications, because the order of elements in the adjacency list doesn't (normally) matter. 邻接列表实际上倾向于支持向量而不是许多应用程序,因为邻接列表中的元素顺序(通常)不重要。 This means when you add elements, it's normally to the end of the container, and when you delete an element, you can swap it to the end of the container first, so you only ever add or delete at the end. 这意味着当你添加元素时,它通常是在容器的末尾,当你删除一个元素时,你可以先将它交换到容器的末尾,所以你只能在最后添加或删除。

Yes, a vector has to copy elements when it expands, but in reality this is almost never a substantial concern. 是的,矢量必须在扩展时复制元素,但实际上这几乎不是一个重要的问题。 In particular, the exponential expansion rate of a vector means that the average number of times elements get copied tends toward a constant -- and in a typical implementation, that constant is about 3. 特别是,向量的指数扩展率意味着元素被复制的平均次数倾向于常数 - 并且在典型的实现中,该常量约为3。

If you're in a situation where the copying honestly is a real problem (eg, copying elements is extremely expensive), my next choice after vector still wouldn't be list. 如果你真的存在真正的问题(例如,复制元素非常昂贵),我在矢量后的下一个选择仍然不会是列表。 Instead, I'd probably consider using std::deque instead. 相反,我可能会考虑使用std :: deque。 It's basically a vector of pointers to blocks of objects. 它基本上是指向对象块的指针向量。 It rarely has to copy anything to do an expansion, and on the rare occasion that it does, all it has to copy is the pointers, not the objects. 它很少需要复制任何东西来进行扩展,并且在罕见的情况下,它必须复制的只是指针,而不是对象。 Unless you need the other unique capabilities of a deque (insert/delete in constant time at either end), a vector is usually a better choice, but even so a deque is almost always a better choice than a list (ie, vector is generally the first choice, deque a fairly close second, and list quite a distant last). 除非你需要deque的其他独特功能(在两端的常量时间内插入/删除),矢量通常是更好的选择,但即使如此,deque几乎总是比列表更好的选择(即,矢量通常是第一个选择,deque一个相当接近的第二个,并列出相当遥远的最后)。

The answer depends on use-case. 答案取决于用例。 PS @quasiverse - vectors call realloc when the memory you "::reserve", implicitly or explicitly, runs out PS @quasiverse - 当你“保留”的内存(隐式或显式)耗尽时,向量调用realloc

If you have a constantly changing adjacency list (inserts and deletes), a list would be best. 如果您有一个不断变化的邻接列表(插入和删除),列表将是最好的。 If you have a more or less static adjacency list, and most of the time you are doing traversals/lookups, then a vector would give you the best performance. 如果您有一个或多或少的静态邻接列表,并且大多数时候您正在进行遍历/查找,那么向量将为您提供最佳性能。

STL containers are not rigidly defined, so implementations vary. STL容器没有严格定义,因此实现方式各不相同。 If you're careful you can write your code so that it doesn't care whether it's a vector or a list that's being used, and you can just try them to see which is faster. 如果你小心,你可以编写你的代码,这样它就不关心它是一个向量还是一个正在使用的列表,你可以试着看看哪个更快。 Given the complexity of cache effects, etc., it's nearly impossible to predict the relative speeds with any accuracy. 鉴于缓存效果等的复杂性,几乎不可能以任何精度预测相对速度。

You can add third option to this comparison: list with specialized allocator. 您可以为此比较​​添加第三个选项:带有专用分配器的列表。

Using allocators for small objects of fixed size may greatly increase speed of allocation/deallocation... 对固定大小的小对象使用分配器可以大大提高分配/释放的速度......

本教程网站建议使用列表数组,或者我猜你可以使用列表元素的向量:列表数组列表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM