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

Søren Højsgaard sorenh at math.aau.dk
Fri Dec 13 12:42:31 CET 2013


Romain, Doug and Dirk: Thanks for the replies :)
Søren

-----Original Message-----
From: Romain François [mailto:romain at r-enthusiasts.com] 
Sent: 10. december 2013 19:07
To: Søren Højsgaard
Cc: rcpp-devel at lists.r-forge.r-project.org (rcpp-devel at r-forge.wu-wien.ac.at)
Subject: Re: [Rcpp-devel] How many copies of my object do I make?


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-deve
> l



More information about the Rcpp-devel mailing list