[Rcpp-devel] use of auxiliary functions

romain at r-enthusiasts.com romain at r-enthusiasts.com
Wed Aug 11 11:48:23 CEST 2010





Le 10 août 2010 à 22:10, baptiste auguie <baptiste.auguie at googlemail.com> a écrit :

> Hi,
> 
> On 10 August 2010 07:51, Romain Francois <romain at r-enthusiasts.com> wrote:
>> Le 10/08/10 07:35, baptiste auguie a écrit :
>>> 
>>> I see –– thanks for the clarification (it is indeed what Dirk really
>>> had suggested, the accidental shortcut was mine). This passing by
>>> reference seems very interesting (I pass several large complex arma
>>> matrices in other functions), but I need to work out how it works
>>> inside the functions.
>> 
>> It should make no difference in how you use the object between :
>> 
>> void foo( arma:::cx_mat m ) ;
>> void foo( const arma::cx_mat& m ) ;
> 
> OK, thanks. I have not been able to produce a minimal code that would
> exhibit an improved performance using this passing-by-reference idea.

Hi, 

It would usually make a difference when copying the object that is passed by value is "expensive" to copy. Rcpp objects are very cheap to copy and both copies refer to the same actual data (the same SEXP). 

For internal code my recommendation would be to always use pass by reference and do an explicit call to clone when a real copy (different SEXP) is needed.

Romain

> My naive attempt follows,
> 
> extern "C" {
> 
>  arma::mat dum1(NumericMatrix A)
>  {
>    arma::mat B = Rcpp::as< arma::mat >( A ) ;
>    B=inv(B*38);
>    return (B);
>  }
> 
>  arma::mat dum2(const NumericMatrix& A)
>  {
>    arma::mat B = Rcpp::as< arma::mat >( A ) ;
>    B=inv(B*38);
>    return (B);
>  }
> 
>  RCPP_FUNCTION_1(NumericMatrix, dummy1, NumericMatrix A) {
>    return wrap(dum1(A));
>  }
> 
>  RCPP_FUNCTION_1(NumericMatrix, dummy2, NumericMatrix A) {
>    return wrap(dum2(A));
>  }
> 
> }
> 
> 
> Timing a 10^3 x 10^3 matrix yields similar results for both functions.
> I wonder in what situations passing by reference may improve
> efficiency; also it is not clear to me whether there can be downsides
> to this approach.
> 
> Thanks again,
> 
> baptiste
> 
> 
>> 
>> inside foo, you use m exactly the same way. Although the const here is there
>> to protect you from yourself. Having the const here means that inside foo
>> you are only allowed to call const methods of the arma::cx_mat class, so you
>> can't modify the object.
>> 
>> If you want to be able to modify the object, you could use
>> 
>> void foo( arma::cx_mat& m ) ;
>> 
>>> Thanks again for the precious comments,
>>> 
>>> baptiste
>>> 
>>> PS: my package is now on r-forge, hoping to see if it compiles there too:
>>> 
>>> https://r-forge.r-project.org/scm/viewvc.php/pkg/cda/?root=photonics
>> 
>> cool. I'll make a few targetted comments when I have time to read it more
>> carefully, but so far it looks good.
>> 
>>> On 10 August 2010 01:38, Davor Cubranic<cubranic at stat.ubc.ca>  wrote:
>>>> 
>>>> On 2010-08-07, at 7:03 PM, baptiste auguie wrote:
>>>> 
>>>>> Thanks Davor, Douglas and Dirk –– all your comments have been very
>>>>> helpful and I used them to improve my code (along with getting a
>>>>> better understanding of C++). The only thing I haven't tried yet is
>>>>> avoid duplicating the objects in memory using const (seems tricky from
>>>>> what I read on the net).
>>>> 
>>>> Using 'const' won't save you from duplicating objects: all it does is
>>>> mark a variable/parameter as a constant, so that you can't accidentally
>>>> change it. What does save you from duplication is passing arguments by
>>>> reference. And passing arguments by reference is often combined with marking
>>>> them 'const' for safety, because accidentally changing them would introduce
>>>> wide-ranging bugs into your code that could be difficult to find.
>>>> 
>>>> Also, note that passing by const reference only saves space for complex
>>>> objects, not primitive types like doubles and consts. So for the 'euler'
>>>> function you used in your example, it would be recommended to make its
>>>> signature:
>>>> 
>>>> arma::mat euler(const double phi, const double theta, const double psi);
>>>> In other words, 'phi', 'theta', and 'psi' are doubles, which I'm passing
>>>> as constants.
>>>> 
>>>> While something like matrix multiply could be:
>>>> 
>>>> arma::mat mul(const arma::mat&  a, const arma::mat&  b);
>>>> Here, 'a' and 'b' are matrix objects, which I'm passing by constant
>>>> reference.
>>>> 
>>>> Hope this helps.
>>>> 
>>>> Davor
>> 
>> --
>> Romain Francois
>> Professional R Enthusiast
>> +33(0) 6 28 91 30 30
>> http://romainfrancois.blog.free.fr
>> |- http://bit.ly/aAyra4 : highlight 0.2-2
>> |- http://bit.ly/94EBKx : inline 0.3.6
>> `- http://bit.ly/aryfrk : useR! 2010
>> 
>> 
> 
> 
> 
> -- 
> ____________________
> 
> Dr. Baptiste Auguié
> 
> Departamento de Química Física,
> Universidade de Vigo,
> Campus Universitario, 36310, Vigo, Spain
> 
> tel: +34 9868 18617
> http://webs.uvigo.es/coloides
> ____________________
> _______________________________________________
> 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