简体   繁体   English

在std ::容器中存储值与指针之间进行选择时的注意事项

[英]Considerations when choosing between storing values vs pointers in std:: containers

When storing objects in standard collections, what considerations should one think of when deciding between storing values vs pointers? 在标准集合中存储对象时,在决定存储值还是指针之间应该考虑什么考虑因素? Where the owner of these collections (ObjectOwner) is allocated on the heap. 这些集合的所有者(ObjectOwner)在堆上分配的位置。 For small structs/objects I've been storing values, while for large objects I've been storing pointers. 对于小型结构/对象,我一直存储值,而对于大型对象,我一直存储指针。 My reasoning for this was that when standard containers are resized, their contents are copied (small copy ok, big copy bad). 我这样做的原因是,当调整标准容器的大小时,将复制其内容(小的复制就可以了,大的复制就不好了)。 Any other things to keep in mind here? 还有其他需要记住的事情吗?

class ObjectOwner
{
   public:
     SmallObject& getSmallObject(int smallObjectId);
     HugeObject* getHugeObject(int hugeObjectId);

   private:
     std::map<int, SmallObject> mSmallObjectMap; 
     std::map<int, HugeObject *> mHugeObjectMap; 
};

Edit: 编辑:

an example of the above for more context: 以上示例的更多背景:

  • Create/Delete items stored in std::map relatively infrequently ( a few times per second) 相对很少(每秒几次)创建/删除存储在std :: map中的项目
  • Get from std::map frequently (once per 10 milliseconds) 经常从std :: map获取(每10毫秒一次)
  • small object: < 32 bytes 小对象:<32个字节
  • huge object: > 1024 bytes 大对象:> 1024个字节

I would store object by value unless I need it through pointer. 除非需要通过指针,否则我将按值存储对象。 Possible reasons: 可能的原因:

  • I need to store object hierarchy in a container (to avoid slicing) 我需要将对象层次结构存储在容器中(以避免切片)
  • I need shared ownership 我需要共享所有权

There are possibly other reasons, but reasoning by size is only valid for some containers ( std::vector for example) and even there you can make object moving cost minimal (reserve enough room in advance for example). 可能还有其他原因,但是按大小进行推理仅对某些容器有效(例如std::vector ),甚至在那里,您也可以使对象移动成本最小化(例如,提前预留足够的空间)。 You example for object size with std::map does not make any sense as std::map does not relocate objects when growing. 您使用std::map表示对象大小的示例没有任何意义,因为std::map在增长时不会重定位对象。

Note: return type of a method should not reflect the way you store it in a container, but rather it should be based on method semantics, ie what you would do if object is not found. 注意:方法的返回类型不应反映您将其存储在容器中的方式,而应基于方法的语义,即,如果找不到对象,该怎么做。

Only your profiler knows the answer for your SPECIFIC case; 只有您的分析器才知道您的特殊情况的答案; trying to use pointers rather than objects is a reliable way of minimising the amount you copy when a copy must be done (be it a resize of a vector or a copy of the whole container); 尝试使用指针而不是对象是一种可靠的方式,可在必须完成复制时将复制量最小化(可以是调整向量的大小,也可以是整个容器的复制); but sometimes you WANT that copy because it's a snapshot for a thread inside a mutex, and it's faster to copy the container than to hold the mutex and deal with the data. 但是有时您希望复制该副本,因为它是互斥锁中线程的快照,并且复制容器比保存互斥锁和处理数据要快。

Some objects might not be possible to keep in any way other than pointer because they're not copyable. 有些对象可能无法以指针以外的其他方式保留,因为它们是不可复制的。

Any performance gain by using container of pointer could be offset by costs of having to write more copy code, or repeated calls to new(). 通过使用指针容器获得的任何性能提升都可以通过必须编写更多复制代码或重复调用new()的成本来抵消。

There's not a one answer fits all, and before you worry about the performance here you should establish where the performance problems really are. 没有一个适合所有人的答案,在担心性能问题之前,您应该确定性能问题的真正所在。 (Just repeating the point - use a profiler!) (只需重复这一点-使用探查器即可!)

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

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