r - Within C++ functions, how are Rcpp objects passed to other functions (by reference or by copy)? -


i've finished writing new version of abcoptim package using rcpp. around 30x speed ups, i'm happy new version's performance (vs old version), i'm still having concerns on if have space improve performance without modifying code.

within main function of abcoptim (written in c++) i'm passing around rcpp::list object containing "bees positions" (numericmatrix) , numericvectors important information algorithm itself. question is, when i'm passing rcpp::list object around other functions, e.g.

#include <rcpp.h>  using namespace rcpp;  list abcinit([some input]){[some code here]}; void abcfun2(list x){[some code here]}; void abcfun3(list x){[some code here]};  list abcmain([some input]) {   list x = abcinit([some input]);   while ([some statement])   {     abcfun2(x);     abcfun3(x);   }   ...    return list::create(x["results"]); } 

what rcpp within while loop? x object passed reference or deep copy functions abcfun2 , abcfun3? i've seen usage of 'const list&x', tells me can pass rcpp objects using pointers, thing need list variable (and no constant), there anyway improve this? i'm afraid iterative copy of x list can slowing down code.

ps: i'm still new c++, furthermore i'm using rcpp learn c++.

there no deep copy in rcpp unless ask clone. when pass value, making new list object uses same underlying r object.

so different small between pass value , pass reference.

however, when pass value, have pay price protecting underlying object 1 more time. might incur cost rcpp relies on recursive not efficient r_preserveobject.

my guideline pass reference whenever possible don't pay protecting price. if know abcfun2 won't change object, i'd advise passing reference const : abcfun2( const list& ). if going make changes list, i'd recommend using abcfun2( list& ).

consider code:

#include <rcpp.h> using namespace rcpp  ;  #define dbg(msg,x) rprintf("%20s sexp=<%p>. list=%p\n", msg, (sexp)x, &x ) ;  void fun_copy( list x, const char* idx ){     x[idx] = "foo" ;     dbg( "in fun_copy: ", x) ;  } void fun_ref( list& x, const char* idx ){     x[idx] = "bar" ;     dbg( "in fun_ref: ", x) ; }   // [[rcpp::export]] void test_copy(){      // create list of 3 components     list data = list::create( _["a"] = 1, _["b"] = 2 ) ;     dbg( "initial: ", data) ;      fun_copy( data, "a") ;     dbg( "\nafter fun_copy (1): ", data) ;      // alter 1st component of ths list, passed value     fun_copy( data, "d") ;     dbg( "\nafter fun_copy (2): ", data) ;   }  // [[rcpp::export]] void test_ref(){      // create list of 3 components     list data = list::create( _["a"] = 1, _["b"] = 2 ) ;     dbg( "initial: ", data) ;      fun_ref( data, "a") ;     dbg( "\nafter fun_ref (1): ", data) ;      // alter 1st component of ths list, passed value     fun_ref( data, "d") ;     dbg( "\nafter fun_ref (2): ", data) ;   } 

all i'm doing pass list function, update , print information pointer underlying r object , pointer list object ( this ) .

here results of happens when call test_copy , test_ref:

> test_copy()            initial:  sexp=<0x7ff97c26c278>. list=0x7fff5b909fd0        in fun_copy:  sexp=<0x7ff97c26c278>. list=0x7fff5b909f30  after fun_copy (1):  sexp=<0x7ff97c26c278>. list=0x7fff5b909fd0 $a [1] "foo"  $b [1] 2         in fun_copy:  sexp=<0x7ff97b2b3ed8>. list=0x7fff5b909f20  after fun_copy (2):  sexp=<0x7ff97c26c278>. list=0x7fff5b909fd0 $a [1] "foo"  $b [1] 2 

we start existing list associated r object.

           initial:  sexp=<0x7fda4926d278>. list=0x7fff5bb5efd0 

we pass value fun_copy new list using same underlying r object:

       in fun_copy:  sexp=<0x7fda4926d278>. list=0x7fff5bb5ef30 

we exit of fun_copy. same underlying r object again, , our original list :

after fun_copy (1):  sexp=<0x7fda4926d278>. list=0x7fff5bb5efd0 

now call again fun_copy time updating component not on list: x["d"]="foo".

       in fun_copy:  sexp=<0x7fda48989120>. list=0x7fff5bb5ef20 

list had no choice create new underlying r object, object underlying local list. therefore when out of get_copy, our original list original underlying sexp.

after fun_copy (2):  sexp=<0x7fda4926d278>. list=0x7fff5bb5efd0 

the key thing here first time "a" on list, updated data directly. because local object fun_copy , outer object test_copy share same underlying r object, modifications inside fun_copy propagated.

the second time, fun_copy grows local list object, associating brand new sexp not propagate outer function.

now consider happens when pass reference :

> test_ref()            initial:  sexp=<0x7ff97c0e0f80>. list=0x7fff5b909fd0         in fun_ref:  sexp=<0x7ff97c0e0f80>. list=0x7fff5b909fd0    after fun_ref(1):  sexp=<0x7ff97c0e0f80>. list=0x7fff5b909fd0 $a [1] "bar"  $b [1] 2          in fun_ref:  sexp=<0x7ff97b5254c8>. list=0x7fff5b909fd0    after fun_ref(2):  sexp=<0x7ff97b5254c8>. list=0x7fff5b909fd0 $a [1] "bar"  $b [1] 2  $d [1] "bar" 

there 1 list object 0x7fff5b909fd0. when have new sexp in second call, correctly gets propagated outer level.

to me, behavior when passing references easier reason with.


Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -