[Rcpp-devel] trying to insert a number as first element of already existing vector

Jan van der Laan rhelp at eoos.dds.nl
Mon Dec 10 12:28:05 CET 2018


For performance memcpy is probably fastest. This gives the same 
performance a c().

// [[Rcpp::export]]
NumericVector mybar3(NumericVector x, double firstelem) {
   NumericVector result(x.size() + 1);
   result[0] = firstelem;
   std::memcpy(result.begin()+1, x.begin(), x.size()*sizeof(double));
   return result;
}


Or a more general version concatenating vector of arbitrary lengths:


// [[Rcpp::export]]
NumericVector mybar4(NumericVector x, NumericVector y) {
   NumericVector result(x.size() + y.size());
   std::memcpy(result.begin(), x.begin(), x.size()*sizeof(double));
   std::memcpy(result.begin()+x.size(), y.begin(), y.size()*sizeof(double));
   return result;
}



 > n=1E7
 > testvec = c(1,seq_len(n))
 > testelem <- 7
 > microbenchmark(c(testelem, testvec), mybar(testvec,testelem),
+   mybar2(testvec,testelem),
+   mybar3(testvec,testelem),
+   mybar4(testvec,testelem)
+   )
Unit: milliseconds
                       expr       min        lq      mean    median   uq 
       max neval
       c(testelem, testvec)  36.48577  36.93754  41.10550  43.76742 
44.20709  46.09741   100
   mybar(testvec, testelem) 102.54042 103.21756 106.88749 104.32033 
110.31527 119.55512   100
  mybar2(testvec, testelem)  95.64696  96.19447 100.24691 102.61380 
103.58189 109.28290   100
  mybar3(testvec, testelem)  36.45794  36.87915  40.43486  37.18063 
43.49643  95.49049   100
  mybar4(testvec, testelem)  36.51334  37.05409  41.39680  43.20627 
43.57958  94.95482   100


Best,
Jan



On 10-12-18 12:10, Serguei Sokol wrote:
> Le 09/12/2018 à 09:35, Mark Leeds a écrit :
>> Hi All: I wrote below and it works but I have a strong feeling there's 
>> a better way to do it.
> If performance is an issue, you can save few percents of cpu time by 
> using std::copy() instead of explicit for loop. Yet, for this operation 
> R's c() remains the best bet. It is more then twice faster than both 
> Rcpp versions below:
> 
> #include <Rcpp.h>
> using namespace Rcpp;
> 
> // [[Rcpp::export]]
> std::vector<double> mybar(const std::vector<double>& x, double firstelem) {
>    std::vector<double> tmp(x.size() + 1);
>    tmp[0] = firstelem;
>    for (int i = 1; i < (x.size()+1); i++)
>      tmp[i] = x[i-1];
>    return tmp;
> }
> // [[Rcpp::export]]
> std::vector<double> mybar2(const std::vector<double>& x, double 
> firstelem) {
>    std::vector<double> tmp(x.size() + 1);
>    tmp[0] = firstelem;
>    std::copy(x.begin(), x.end(), tmp.begin()+1);
>    return tmp;
> }
> 
> /*** R
> library(microbenchmark)
> n=100000
> testvec = c(1,seq_len(n))
> testelem <- 7
> microbenchmark(c(testelem, testvec), mybar(testvec,testelem), 
> mybar2(testvec,testelem))
> */
> 
> # Ouput
> Unit: microseconds
>                        expr     min       lq      mean   median        uq
>        c(testelem, testvec) 247.098 248.5655  444.8657 257.3300  630.7725
>    mybar(testvec, testelem) 594.978 622.3560 1226.5683 637.0230 1386.8385
>   mybar2(testvec, testelem) 576.191 604.7565 1029.2124 616.1055 1351.6740
>         max neval
>    7587.977   100
>   22149.605   100
>   11651.831   100
> 
> 
> Best,
> Serguei.
> 
>> I looked on the net and found some material from back in ~2014 about 
>> concatenating
>> vectors but I didn't see anything final about it. Thanks for any 
>> insights.
>>
>> Also, the documentation for Rcpp is beyond incredible (thanks to dirk, 
>> romain, kevin and all the other people I'm leaving out )  but is there 
>> a general methodology for finding equivalents of R functions. For 
>> example, if I want a cumsum function in Rcpp, how do I know whether to 
>> use the stl with accumulate or if there's already one built in so
>> that I just call cumsum.
>>
>> Thanks.
>>
>> #=======================================================
>>
>> #include <Rcpp.h>
>> using namespace Rcpp;
>>
>> // [[Rcpp::export]]
>> std::vector<double> mybar(const std::vector<double>& x, double 
>> firstelem) {
>>    std::vector<double> tmp(x.size() + 1);
>>    tmp[0] = firstelem;
>>    for (int i = 1; i < (x.size()+1); i++)
>>      tmp[i] = x[i-1];
>>    return tmp;
>> }
>>
>> /*** R
>>
>> testvec = c(1,2,3)
>> testelem <- 7
>> mybar(testvec,testelem)
>>
>> */
>>
>> #===============================
>> # OUTPUT FROM RUNNING ABOVE
>> #=================================
>>  > testvec <-  c(1,2,3)
>>  > testelem <- 7
>>  > mybar(testvec,testelem)
>> [1] 7 1 2 3
>>  >
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> 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
>>
> 
> _______________________________________________
> 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