Eigen库优化:能否返回表达式而非向量以提升运算效率?
如何让函数返回表达式而非向量以优化Eigen代码性能
完全可以通过返回Eigen表达式类型替代具体的Vector3<T>,避免创建中间临时向量,让整个表达式g = f(a1, b1).cwiseProduct(t1) + f(a2, b2).cwiseProduct(t2)延迟到赋值时一次性计算,大幅提升效率。
具体实现方式
情况1:f是Eigen现有表达式的组合
如果f的逻辑可以用Eigen内置运算(加减乘除、逐元素运算等)组合实现,直接返回组合后的表达式即可:
#include <Eigen/Core> template<typename T> auto f(const Eigen::Vector3<T>& x, const Eigen::Vector3<T>& y) { // 示例逻辑:x逐元素平方 + y逐元素开方,直接返回表达式 return x.cwiseProduct(x) + y.cwiseSqrt(); } // 使用示例 int main() { Eigen::Vector3d a1(1,2,3), b1(4,5,6), t1(0.1,0.2,0.3); Eigen::Vector3d a2(7,8,9), b2(10,11,12), t2(0.4,0.5,0.6); Eigen::Vector3d g; // 整个表达式延迟到赋值给g时才计算,无中间临时Vector3d创建 g = f(a1, b1).cwiseProduct(t1) + f(a2, b2).cwiseProduct(t2); return 0; }
情况2:f是自定义的逐元素运算
如果f需要实现自定义逐元素逻辑,先定义运算的functor,再用binaryExpr封装成表达式返回:
#include <Eigen/Core> // 自定义二元运算:每个元素计算 3*x + 2*y template<typename T> struct CustomBinaryOp { EIGEN_EMPTY_STRUCT_CTOR(CustomBinaryOp) template<typename Scalar> EIGEN_DEVICE_FUNC Scalar operator()(const Scalar& x, const Scalar& y) const { return 3 * x + 2 * y; } }; // 函数f返回BinaryExpr表达式对象 template<typename T> auto f(const Eigen::Vector3<T>& x, const Eigen::Vector3<T>& y) { return x.binaryExpr(y, CustomBinaryOp<T>()); } // 使用示例 int main() { Eigen::Vector3d a1(1,2,3), b1(4,5,6), t1(0.1,0.2,0.3); Eigen::Vector3d a2(7,8,9), b2(10,11,12), t2(0.4,0.5,0.6); Eigen::Vector3d g; // 所有运算合并到赋值时执行,无中间临时向量 g = f(a1, b1).cwiseProduct(t1) + f(a2, b2).cwiseProduct(t2); return 0; }
关键注意事项
- 变量生命周期:表达式对象仅持有输入向量的引用,因此
a1、b1等变量的生命周期必须覆盖到g的赋值操作,避免悬空引用。 - C++版本兼容:C14及以后可直接用
auto推导返回类型;C11需用decltype显式指定,示例:template<typename T> auto f(const Eigen::Vector3<T>& x, const Eigen::Vector3<T>& y) -> decltype(x.binaryExpr(y, CustomBinaryOp<T>())) { return x.binaryExpr(y, CustomBinaryOp<T>()); }
内容的提问来源于stack exchange,提问作者0xbadf00d
相关产品推荐
相关产品推荐

