简体   繁体   中英

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. 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)
  • Get from std::map frequently (once per 10 milliseconds)
  • small object: < 32 bytes
  • huge object: > 1024 bytes

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). You example for object size with std::map does not make any sense as std::map does not relocate objects when growing.

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().

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!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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