使用C ++容器最小化内存开销(std :: map和std :: vector太贵)

时间:2014-11-16 21:39:07

标签: c++ c++11 vector map stl

我希望能够处理大量的数据记录,大约20个uint8_t个密钥将与每个密钥相关联(按<int, struct>排序)。这些对在~10字节时非常轻量级,需要动态分配。

最初,我使用了int,但在研究了与向量相关的开销之后,即{/ 1}}

  

总计3个机器字+ std::map<uint8_t, std::vector<int, struct>> * capacity()

here; sizeof(element)“通常有足够的空间容纳实际数量的元素”,这似乎是有害的。

我可以使用std :: map代替向量,但~32 bytes per node的开销对于这种轻量级对也变得非常昂贵。

我不熟悉Boost和其他C ++库,所以想知道是否有人可以建议我可以避免手动动态内存分配的解决方案?


编辑:为了澄清注释中的几个问题,存储的struct将包含3个short(开头),没有其他数据结构。我预计capacity()的长度不会超过1.5 * 10 ^ 8,并且理解这将达到~1.4 GiB(感谢@dyp)。

我认为问题是如何管理向量capacity(),以便通过vector重新分配保持在最低限度。我也不确定capacity()(C ++ 11)的效率

1 个答案:

答案 0 :(得分:2)

跟进@ NielKirk关于std :: vector&lt;&gt;的观点而不是键的映射,只有256种可能性你也可以考虑std :: array&lt;&gt; (或者甚至是C风格的数组)用于键。

至于std :: pair&lt; int,struct&gt;元素,初始实现将它们作为std :: vector&lt; std :: pair&lt; int,struct&gt;&gt;的成员。收藏,你说

  

我可以使用std :: map代替向量,但是对于这样的轻量级对,每个节点大约32字节的开销也变得非常昂贵。

这意味着元素的int部分是唯一的,因为您没有提到std :: multimap。您可以查看Google sparsehashhttp://code.google.com/p/sparsehash/)。从项目主页:

  

极其节省内存的hash_map实现。 2位/进入开销! SparseHash库包含多个哈希映射实现,包括针对空间或速度进行优化的实现。

     

这些哈希表实现在API中类似于SGI的hash_map类和tr1 unordered_map类,但具有不同的性能特征。在C ++代码中,通过sparse_hash_map或dense_hash_map替换hash_map或unordered_map很容易。   

我以前用过它,从来没有遇到过问题。您的uint8_t密钥可以索引到(std :: vector / std :: array / C-array)集合 KCH 的哈希映射。如果你愿意,你甚至可以将 KCH 定义为对象集合,每个对象都包含一个hashmap,因此每个 KCH [i] 都可以实现一个方便的界面来处理{{1该键的对象。你有一个“坏键”元素作为集合中非键元素的默认元素,引用a)单个空虚拟散列图或b)适当处理意外键值的“坏键对象”。

这样的事情:

std::pair<int, struct>

将所有typedef std::pair<int, struct> myPair; typedef google::sparse_hash_map<int, myPair> myCollectionType; typedef google::sparse_hash_map<int, myPair>::iterator myCollectionIter; myCollectionType dummyHashMap; std:array<myCollectionType, 256> keyedArray; 元素初始化为keyedArray,然后使用不同的哈希映射填写有效密钥。

同样,包含对象:

dummyHashMap

将256个键控数组元素初始化为class KeyedCollectionHandler { public: virtual bool whatever(parm); ... private: myCollectionType collection; }; class BadKeyHandler : public KeyedCollectionHandler { public: virtual bool whatever(parm){ // unknown or unexpected key, handle appropriately } ... }; BadKeyHandler badKeyHandler; ,填入badKeyHandler个对象以获得良好的键值。