[Rcpp-devel] How many copies of my object do I make?

Romain François romain at r-enthusiasts.com
Tue Dec 10 19:06:35 CET 2013


Le 9 déc. 2013 à 23:14, Søren Højsgaard <sorenh at math.aau.dk> a écrit :

> Dear all,
> Using RcppEigen I've created a function for converting a sparse matrix (a dgCMatrix) to a standard dense matrix:
> 
> typedef Eigen::SparseMatrix<double> SpMatd;
> typedef Eigen::MappedSparseMatrix<double> MSpMat;
> 
> // [[Rcpp::export]]
> SEXP do_dgCMatrix2matrix ( SEXP XX_ ){
>  S4 DD(wrap(XX_));
>  List dn = clone(List(DD.slot("Dimnames")));
>  SpMatd X(as<SpMatd>(XX_));
>  Eigen::MatrixXd dMat;
>  dMat = Eigen::MatrixXd( X );
>  NumericMatrix Xout(wrap(dMat));
>  Xout.attr("dimnames") = dn;
>  return Xout;
> }
> 
> The function does what I expect it to, but I am curious about how many times I really create some sort of "copy" of my input matrix and when all I do is put a small layer of "vernish" over my input matrix?
> 
> 1) dMat is dense matrix, and that must (I guess) refer to new "object"??
> 
> 2) X is a sparse matrix, and I suppose it is a new object?? 

Data copy is done in the as implementation for SpMatd, see here for what really happens:
https://github.com/RcppCore/RcppEigen/blob/master/inst/include/RcppEigenWrap.h#L301

So you pay for copying data from the R representation to the Eigen representation, which are not the same. 

You don’t pay for a copy from what as returns to X because of RVO. Most compilers will optimize this for you. 

> 2') If I had declared it to be MSpMat, then it would really just be the input object with a few bells and whistles??

Yes. As far as I understand that code:
https://github.com/RcppCore/RcppEigen/blob/master/inst/include/RcppEigenWrap.h#L284

> 3) But how about DD and Xout? Are they new objects (in terms of memory usage)?

To start with, you don’t need wrap(XX_), as XX_ is a SEXP, and you could have S4 in the signature of the function, which would make the intent clearer. By the same token you can have your function return a NumericMatrix. 

S4 DD ; just makes sure the data you pass to it is an S4 object. It does not do deep copy of your data. 

wrap(dMat) causes copy of the eigen representation into an R representation. This makes data copy. wrap returns a SEXP. 
When this SEXP gets into Xout, no copy is done. 

Romain

> Put differently, if my input matrix occupies B bytes of memory, how many times B have I then created along the way?
> 
> All the best
> Søren
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel



More information about the Rcpp-devel mailing list