如何实现sparse_vector类

时间:2010-05-11 06:14:44

标签: c++ vector sparse-matrix sparse-array

我正在实现一个模板化的sparse_vector类。它就像一个向量,但它只存储与默认构造值不同的元素。

因此,sparse_vector会为值为非T()的所有索引存储 lazily-sorted 索引值对。

我的实现基于数值库中现有的稀疏向量 - 尽管我也会处理非数字类型T.我查看了boost::numeric::ublas::coordinate_vectoreigen::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字节类型,可能还有一些对齐优势?

在我看来,对的矢量是更好的解决方案,但两个容器都选择了另一种解决方案。为什么呢?

2 个答案:

答案 0 :(得分:2)

将索引放在单独的列表中会使查找速度更快 - 正如您所建议的那样,它会更有效地使用缓存,特别是如果T很大。

如果您想实施自己的,为什么不使用std::map(或std::unordered_map)?密钥会更大,但实施时间将接近于零!

答案 1 :(得分:1)

实际上,似乎他们重新发明了轮子(可以这么说)。

我个人会根据您的需要考虑2个库:

  • Loki,Loki::AssocVector - &gt;通过vector实现的地图界面(您希望这样做)
  • Boost.Iterator,其iterator_adaptor类。通过Composition实现新容器非常容易。

作为评论,我会注意到您可能希望更加通用,其值与T()不同,因为这会将T强加为DefaultConstructible。你可以提供一个T const&的构造函数。在编写通用容器时,最好尽量减少必要的要求(只要不影响性能)。

另外,我想提醒您,使用vector存储的想法对于少量值非常有用,但您可能希望将基础容器更改为经典mapunordered_map如果值的数量增加。它可能值得分析/计时。请注意,STL使用容器适配器(如stack)提供此功能,即使它可能会使实现稍微困难。

玩得开心。