如果存储指针,std::list 是否比 std::vector 更好?
我通常避免使用 std::list,但在存储指针的情况下,使用 std::list 会更有利吗,因为我可以随机插入指针而不必移动所有其他指针?与 std::vector
相比,这有哪些优点和缺点
谢谢
I generally avoid std::list, but in a case where I'm storing pointers, would it be more advantageous to use a std::list since I could then randomly insert pointers without having to move all my other pointers? What advantages and disadvantages would this present over a std::vector<Some*>
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
由于指针的复制构造很简单,因此这里的决定不是关于哪个更适合存储指针,而是哪个更适合您的需求。
如果您确实需要进行大量随机插入(和删除?),那么
list
可以工作得更好,尽管这不是一个简单的决定 - 也许带有保留空间的vector
会更好,即使如此。您是否希望列表的每个节点开销只是为了存储指针?在 32 位 Windows 上,列表中的每个条目 12 个字节,加上堆管理开销,每个条目总共 20 多个字节。随着时间的推移,这也无助于数据局部性。同时,vector
每个条目使用四个字节(同样是 32 位),并保证将其元素存储在连续的块中。无论哪种方式,您都必须在
erase
/clear
/销毁容器时处理内存清理,除非您将指针元素包装为某种智能指针。简化Some*
内存管理的另一种方法是 增强指针容器。另请参阅此处对
list
、的一些分析矢量
和双端队列
。就我个人而言,我越来越认为list
在主流中没有那么有用。Since copy construction of a pointer is trivial, the decision here is not about whether one or the other is better for storing pointers but which is better for your needs.
If you really need to do lots of random inserts (and deletes?) then
list
could work better though it's not a simple decision - perhaps avector
with reserved space would be preferable, even then. Do you want the per-node overhead of alist
just to store a pointer? On 32-bit Windows, that's 12 bytes per entry in thelist
, plus heap management overhead for a total of 20+ bytes per entry. This does not help data locality over time either. Meanwhile,vector
uses four bytes per entry (again on 32-bit) and is guaranteed to store its elements in a contiguous block.You have to deal with memory cleanup on
erase
/clear
/destruction of the container either way, unless you wrap the pointer element as a smart pointer of some kind. An alternative to ease memory management of yourSome*
s would be one of the Boost pointer containers.See also here for some analysis of
list
,vector
anddeque
. Personally, I'm increasingly of the opinion thatlist
is not that useful in the mainstream.我认为尤其是指针应该考虑使用
std::vector
而不是std::list
在随机位置进行多次插入/删除。复制指针的成本非常低(事实上,我希望我的标准库实现使用 CPU 内部函数来完成此操作),因此的局部性更高std::vector
的数据可能远远超过理论上更好的随机插入/删除的std::list
适应性。无论如何,您必须测量您的应用程序(而不是人工测试用例)才能确定。
I think it's especially pointers where using
std::vector
instead ofstd::list
should be considered even with many insertions/removals at random positions. Pointers are very cheap to copy (in fact, I'd expect my standard library implementation to use CPU intrinsics to do this), so that the higher locality ofstd::vector
's data might by far outweigh the theoretically better fitness ofstd::list
for random insertions/removals.Anyway, you will have to measure your application (and not an artificial test case) to know for sure.
一般来说,您的第一选择应该是
vector
——同样,当您存储指针时。将这个决定与 C 中的这个问题(-ish)进行比较:When do I choice
over
?
有一些情况,但首先检查是否可以应用“更简单”的数据结构,即
向量
。In general, your first choice should be
vector
-- also, when you store pointers.Compare the decision with this question in C (-ish): When do I choose
over
?
There are cases, but first check if you can apply the "easier" data structure, i.e. the
vector
.一般来说,当您需要一个存储某些内容然后随机删除它的容器时,最好的选择是
set
。要删除某些内容,您需要先找到它,向量和列表的复杂度为O(n)
,集合的复杂度为O(log(n))
。如果找到,则删除它对于列表来说是即时的,但对于向量来说是O(n)
,对于集合来说又是O(log(n))。所以:
从此搜索或删除
容器;
list
;向量
是内存和缓存效率最高的。如果您知道元素的数量,那么使用reserve()
可以使其内存效率达到 100%。Generally when you need a container which stores something and then randomly deletes it then the best would be a
set
. To delete something you need to find it first, which isO(n)
for vector and list andO(log(n))
for set. If found then deleting it is instant for list butO(n)
for vector, and again O(log(n)) for set.So:
vector
if you very rarelysearch or delete from this
container;
list
if you very rarely search in container;set
otherwise.A
vector
is the most memory and cache efficient. If you know number of elements then usingreserve()
you can make it 100% memory efficient.根据基准测试研究,我更喜欢使用向量,除非有其他强大的用例来支持链表(带有一些开销信息)。但要以更好的方式解决插入和删除效率低下的问题(平均而言)。
我的想法如下:
创建/添加新的 SomeObject 元素:
删除现有的 SomeObject 元素:
使用线性搜索时间处理向量的现有 SomeObject 元素:
欢迎任何其他想法...
Based on bench marking studies, I prefer to use vector unless there are other strong use cases to support linked list (with some overhead info). But take care of the insertion and removal inefficiencies (on average) in a better way.
Here goes my thoughts:
Creating/adding new SomeObject element:
Deleting an existing SomeObject element:
Working on existing SomeObject elements of the vector using Linear Search time:
Any other thoughts are welcome...
我假设您询问 [
std::list
由于许多间接而会非常慢]Vs
std::vector
:Foo
对象Foo
可以是抽象的删除
您的对象std::list:
删除
对象Foo
对象Foo
不能是抽象的编辑:
我意识到在一种情况下,除非您的对象由其他人拥有,否则 std::vector 不起作用。考虑这个递归的事情
I assume you ask about [
std::list<Foo*>
would be really slow due to many indirections]Vs
std::vector
:Foo
objectsFoo
can be abstractdelete
your objects manuallystd::list
:delete
objectsFoo
objectsFoo
cannot be abstractEDIT:
I realised that there is one situation when std::vector does not work unless your objects are owned by someone else. Consider this recursive thing