C++ 如何";“移动”;特征向量

C++ 如何";“移动”;特征向量,c++,c++11,move,eigen,C++,C++11,Move,Eigen,我最近一篇帖子中的一位评论员告诉我,我需要更好地利用c++11移动语义来处理代码中的瓶颈。下面是需要修复的问题的简化版本 #include <iostream> #include <Eigen/Dense> #include <vector> void makeCopy(std::vector<Eigen::VectorXd> &oldV){ int n = oldV.size(); std::vector<Eige

我最近一篇帖子中的一位评论员告诉我,我需要更好地利用c++11移动语义来处理代码中的瓶颈。下面是需要修复的问题的简化版本

#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;
}

但是我发现它慢了一些。@vsoftco和@ggael都提到返回修改后的复制参数会更快,而不是再次复制,我同意这一点,但我怀疑这是否适用于我的实际代码。我可以稍后再问这个问题,但这将是一个单独的问题/线索。

您看的不是正确的一行。如果一个副本是强制性的,那么你就无法摆脱它。尽管如此,最好避免for循环和right:

std::vector<Eigen::VectorXd> mandatoryCopy = oldV;
这将执行廉价的指针交换。你会得到:

void makeCopy(std::vector<Eigen::VectorXd> &oldV){
  std::vector<Eigen::VectorXd> V = oldV;
  // do something with V
  std::swap(oldV,V);
}

因为你现在创建了两个副本,所以速度较慢。只需在函数内部直接使用
oldV
,无需再复制。在函数退出时,当您按值传递参数时,参数不会被修改。
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;
}
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
}