如何"move"特征::VectorXd s
How to "move" Eigen::VectorXd s
我最近的一篇文章中的评论者告诉我,我需要更好地利用C 11 Move-Semantics来处理我的代码中的瓶颈。以下是需要修复的简化版本。
#include <iostream>
#include <Eigen/Dense>
#include <vector>
void makeCopy(std::vector<Eigen::VectorXd> &oldV){
int n = oldV.size();
std::vector<Eigen::VectorXd> mandatoryCopy;
mandatoryCopy.resize(n);
for(int i = 0; i < n; i++){
mandatoryCopy[i] = oldV[i];
}
// swap the two
oldV = mandatoryCopy;
}
int main(int argc, char **argv)
{
// starting vector
int len(1000);
Eigen::VectorXd placeHolder(50);
std::vector<Eigen::VectorXd> v(len, placeHolder);
// copy it a bunch of times
for(int iter = 0; iter < 1000; ++iter){
std::cout << "iter: " << iter << "n";
makeCopy(v);
}
return 0;
}
问题:makeCopy
的for循环内部,oldV[i]
是一个LVALUE,那么我该怎么做mandatoryCopy[i]&& = oldV[i]
之类的事情?这是主要的瓶颈,对吗?我在想类似mandatoryCopy[i]&& = std::move(oldV[i])
的东西,但这显然不会编译。
编辑
根据 @vsoftco的建议,我尝试了
std::vector<Eigen::VectorXd> makeCopy2(std::vector<Eigen::VectorXd> oldV){
int n = oldV.size();
std::vector<Eigen::VectorXd> mandatoryCopy;
mandatoryCopy.resize(n);
for(int i = 0; i < n; i++){
mandatoryCopy[i] = oldV[i];
}
return mandatoryCopy;
}
,但我发现它较慢。@vsoftco和@ggael都提到,返回修改后的复制参数,而不是再次复制,我同意,但我怀疑我的实际代码是否有可能。我稍后可以问一下,但这将是一个单独的问题/线程。
您没有查看正确的行。如果一个副本是强制性的,那么您将无法摆脱它。尽管如此,最好避免循环和正确的循环:
std::vector<Eigen::VectorXd> mandatoryCopy = oldV;
另一方面,您可以通过以下方式替换oldV=mandatoryCopy
来省略第二份副本。
std::swap(oldV,mandatoryCopy);
将执行廉价的指针交换。你得到:
void makeCopy(std::vector<Eigen::VectorXd> &oldV){
std::vector<Eigen::VectorXd> V = oldV;
// do something with V
std::swap(oldV,V);
}
对于功能样式,在您的第二个示例中,您必须直接使用已经是副本的参数:
std::vector<Eigen::VectorXd> makeCopy2(std::vector<Eigen::VectorXd> V){
// do something with V
return V;
}
并使用v = makeCopy2(v);
。
不要忘记使用-std=c++11
编译以获取移动语义副本。
最后,最好将vector<VectorXd>
包装在MatrixXd
中。这将急剧减少内存分配的数量:
void makeCopy3(MatrixXd &oldV){
int n = oldV.cols();
MatrixXd V = oldV;
for(int i = 0; i < n; i++){
V.col(i) *= 0.99;
}
oldV.swap(V); // or oldV = std::move(V); with c++11 enabled
}
相关文章:
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- 特征:模板函数中矩阵的平面图
- 如何在没有数据拷贝的情况下从指针创建一个Eigen VectorXd对象
- basic_string的前导/尾部不区分空格的特征
- 特征 3 类的模板专用化
- 特征 c++:复矩阵的面积双曲正切(atanh)
- C++ 中的特征向量计算
- 根据C++标准的定义实现"is_similar"类型特征
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 有没有办法找到特征矩阵系数的中值?
- 如何将高维数据映射到特征类型?
- 将平面阵列重塑为复杂的特征类型
- 我是否可以拥有大小大于大小限制 (2^32) 的特征::VectorXd
- 如何"move"特征::VectorXd s
- 将std与特征库中的Vectorxd一起使用
- 在MatrixXd和VectorXd之间的特征c++矩阵乘法