我正在实现一个模板化的sparse_vector类。它就像一个向量,但它只存储与默认构造值不同的元素。
因此,sparse_vector会为值为非T()的所有索引存储 lazily-sorted 索引值对。
我的实现基于数值库中现有的稀疏向量 - 尽管我也会处理非数字类型T.我查看了boost::numeric::ublas::coordinate_vector
和eigen::SparseVector
。
两个商店:
size_t* indices_; // a dynamic array
T* values_; // a dynamic array
int size_;
int capacity_;
他们为什么不单纯使用
vector<pair<size_t, T>> data_;
我的主要问题是两个系统的利弊是什么,哪个最终更好?
对向量管理size_和capacity_,并简化了附带的迭代器类;它也有一个内存块而不是两个,所以它会产生一半的重新分配,并且可能有更好的引用位置。
另一种解决方案可能会更快地搜索,因为在搜索过程中缓存行仅填充了索引数据。如果T是8字节类型,可能还有一些对齐优势?
在我看来,对的矢量是更好的解决方案,但两个容器都选择了另一种解决方案。为什么呢?
答案 0 :(得分:2)
将索引放在单独的列表中会使查找速度更快 - 正如您所建议的那样,它会更有效地使用缓存,特别是如果T很大。
如果您想实施自己的,为什么不使用std::map
(或std::unordered_map
)?密钥会更大,但实施时间将接近于零!
答案 1 :(得分:1)
实际上,似乎他们重新发明了轮子(可以这么说)。
我个人会根据您的需要考虑2个库:
Loki::AssocVector
- &gt;通过vector
实现的地图界面(您希望这样做)iterator_adaptor
类。通过Composition实现新容器非常容易。作为评论,我会注意到您可能希望更加通用,其值与T()
不同,因为这会将T
强加为DefaultConstructible。你可以提供一个T const&
的构造函数。在编写通用容器时,最好尽量减少必要的要求(只要不影响性能)。
另外,我想提醒您,使用vector
存储的想法对于少量值非常有用,但您可能希望将基础容器更改为经典map
或unordered_map
如果值的数量增加。它可能值得分析/计时。请注意,STL使用容器适配器(如stack
)提供此功能,即使它可能会使实现稍微困难。
玩得开心。