在Rcpp中实现split()函数

gma*_*man 6 c++ algorithm performance rcpp

我正在尝试在C ++中的R中分别为Vector,Matrix和Data Frame实现本机拆分功能。例如下面的功能用于拆分矢量。

using namespace Rcpp;
using namespace std;
//[[Rcpp::export]]
List splitVecCpp(NumericVector x, NumericVector y) {
std::map<double,NumericVector> output;
 for (int i=0;i<x.size();i++) {
        output[ y[i] ].push_back(x[i]);
      }
           return wrap(output);
}
Run Code Online (Sandbox Code Playgroud)

但这甚至比本地拆分功能要慢。我认为push_back函数会使上述版本变慢,因为它会为每次后推重新分配向量。但我不确定。欢迎任何建议和解释。

接下来矩阵的分割功能如下

//[[Rcpp::export]]
std::map<double,std::set<int> > uniqueCpp(NumericVector x){
std::map<double,std::set<int> > out; 
for(int i=0;i<x.length();i++){
  if(out.count(x[i])){
    std::set<int> temp_set=out.find(x[i])->second;
    temp_set.insert(i);
    out[x[i]]=temp_set;
  }else{
    std::set<int> temp_set;
    temp_set.insert(i);
    out[x[i]]=temp_set;
  }
}
return out;
}

//[[Rcpp::export]]
List splitMatCpp(NumericMatrix splited,NumericVector spliter){
std::map<double,std::set<int> > uniqueSpliter=uniqueCpp(spliter); 
std::map<double,NumericMatrix> output;

for(std::map<double , std::set<int> >::iterator it=uniqueSpliter.begin();it!=uniqueSpliter.end();++it){
  std::set<int> indices=it->second;
  NumericMatrix temp_mat(indices.size(),splited.ncol());
  int j=0;
  for(std::set<int>::iterator index_it=indices.begin();index_it!=indices.end();++index_it){
    temp_mat(j,_)=splited(*index_it,_);
    j++;
  }
  output[it->first]=temp_mat;
 }
 return wrap(output);
}
Run Code Online (Sandbox Code Playgroud)

但是,此实现比矢量的实现要差得多。有没有办法改善这种实现?还是我缺少基本的东西?

我通过使用C ++中的Function对象解决了这些问题。例如

//[[Rcpp::export]]
List splitR(NumericMatrix x,NumericVector y){
 Function sp("split");
 return sp(x,y);

}     
Run Code Online (Sandbox Code Playgroud)

即使此功能与本机拆分也有轻微的性能差异。请解释本机函数和函数对象之间的性能差异?