对于SparseMatrix实现,我们能做的最好的事情是什么?
What's the best we can do for a SparseMatrix implementation?
我使用的是特征矩阵框架和稀疏向量库。我遇到了性能问题,我需要的都是稀疏矢量点积。所以我推出了我自己的SparseMatrix实现,希望它能更快一点:
一点示例代码:
#include <map>
using namespace std ;
struct SparseMatrix
{
map<int, Vector> vals ;
Vector dot( SparseMatrix& o )
{
SparseMatrix *LS, *RS ;
// iterate over the smaller of the 2
if( vals.size() < o.vals.size() )
{
// walk vals
LS = this ;
RS = &o ;
}
else
{
LS = &o ;
RS = this ;
}
// walk LS
Vector sum = 0 ;
for( map<int,Vector>::iterator LSIter = LS->vals.begin() ; LSIter != LS->vals.end() ; ++LSIter )
{
const int& key = LSIter->first ;
// use the key, see if RS has a similar entry.
map<int,Vector>::iterator RSIter = RS->vals.find( key );
if( RSIter != RS->vals.end() )
sum += RSIter->second * LSIter->second ;
}
return sum ;
}
} ;
所以2个向量的点积,比如说有这样的条目:
+---------------+|vec 1||指数值||2 18||7 4||18 33|+---------------++---------------+|vec 2||指数值||2 1||15 87||21 92|+---------------+
则点积为18。
所以,正如你所看到的,我用std::map
来查找元素,看看一个向量中的元素是否在另一个向量里。
由于我只使用整数索引和1d数组,有没有办法让查找更快?我的稀疏矩阵乘法仍然是一个瓶颈(我的代码性能仅略快于Eigen)
有一个向量对:index->value,按索引排序。然后同时迭代两个向量。若两个向量中有相同的索引,则将值相乘,将其相加到结果中,然后转到两个向量的下一对。否则,在对的第一个元素较小的向量上增加迭代索引。
当然,假设你不经常修改数据。
即伪代码:
for i = 0, j = 0; i < vec1.size && j < vec2.size:
if vec1[i].first == vec2[j].first:
result += vec1[i++].second * vec2[j++].second
elif vec1[i].first < vec2[j].first:
i++
else
j++
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 派生类销毁的最佳实践是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- getline() 的原型/库是什么;
- "std::unique_XXX"命名约定背后的基本原理是什么?
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 主线的等价语句是什么
- 在reactor中存储eventHandlers的最佳方式是什么
- c++20[[no.unique_address]]中的新功能是什么
- 在C++17中,引用const字符串的语义应该是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 对于需要精度的定点,最好的乘法算法是什么