用C++11优化矩阵运算的空间和时间效率

最近在segmentfault.com上看到一个问题,提问者想要利用C++11的移动语义,减少矩阵相加时临时对象的构造。受此启发,我实现了一个简单的矩阵类,利用C++11标准中的一些特性,对矩阵运算进行了时间和空间效率的优化。(完整代码:matrix.hmatrix_test.ccrun.sh

用C++11的移动语义,优化矩阵运算的空间效率

C++11的右值引用(T&&),可以将一个变量标记为“临时的”、“在此之后不再需要”,让该变量的使用者可以放心地将其内容“偷”走,而不用担心会有不良后果。利用该特性,可以减少矩阵运算中不必要的临时对象构造和拷贝,实现空间效率的优化。

矩阵加法、减法和数乘

先讨论矩阵加法。

常用的加法函数的声明格式为 T operator+(const T& lhs, const T& rhs); ,例如std::plus。这样符合我们对加法的常识,两个加数在相加前后都不变(不被修改),返回一个临时对象作为结果。这样做的代价是,每次加法都要构造一个临时对象。(这里有个插曲,返回值优化会在 T v = a1 + a2; 中省去一次临时对象构造,但在 T v = a1 + a2 + ... + an; 中仍然要进行n-1次临时对象的构造,临时对象构造不可避免)

而在矩阵运算中,构造临时矩阵代价就更大。因此,除了Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs); 这种常用形式,可以引入另外两种声明形式:

Matrix<T> operator+(const Matrix& lhs, Matrix&& rhs);
Matrix<T> operator+(Matrix&& lhs, const Matrix& rhs);

在连续相加中产生的临时矩阵,匹配到右值引用参数,然后其空间被“偷”走,作为函数返回值传出。再加上返回值优化,就可以在整个加法表达式中不构造任何临时矩阵,全部实现原地运算,优化矩阵加法的空间效率。

实现代码如下:

template <typename T>
Matrix<T> operator+(const Matrix<T>& lhs, Matrix<T>&& rhs) {
  matrix::CheckDimensionMatches(lhs, rhs);
  Matrix<T> result(std::move(rhs));
  result += lhs;
  return result;
}

template <typename T>
Matrix<T> operator+(Matrix<T>&& lhs, const Matrix<T>& rhs) {
  return rhs + std::move(lhs);
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值