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

Mark Leeds markleeds2 at gmail.com
Wed Dec 12 01:55:27 CET 2018


Serguei: Since you were kind enough to time things in my previous question,
I just wanted to follow up with something
I found interesting. I take your code below and only change it in that use
a NumericVector instead of an std::double<vector>
and call it mybar3. Somewhat surprisingly, the timing improved
considerably, even beating c() in R. I only recently learned that
NumericVector could use begin() and end() statements so I'm not the person
to understand why except that, from another thread,
I learned that, to convert to std:: double, deep copies need to be made.
So, maybe that's why ? I'm going to look at Jan's
solution next and, if I find anything interesting there, will send it.

#===================================================================================================

#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;
}

// [[Rcpp::export]]
NumericVector mybar3(NumericVector x, double firstelem) {
   NumericVector tmp(x.size() + 1);
   tmp[0] = firstelem;
   std::copy(x.begin(), x.end(), tmp.begin()+1);
   return tmp;
}

/*** R

library(microbenchmark)
n=10000
testvec = c(1,seq_len(n))
testelem <- 7

temp2 <- mybar2(testvec, testelem)

microbenchmark(c(testelem, testvec), mybar(testvec,testelem),
mybar2(testvec, testelem), mybar3(testvec, testelem))

*/

  microbenchmark(c(testelem, testvec), mybar(testvec,testelem),
mybar2(testvec, testelem), mybar3(testvec, testelem))
Unit: microseconds
                      expr    min      lq     mean  median      uq     max
neval
      c(testelem, testvec) 14.780 30.9765 33.42152 32.5605 33.8890
74.750   100
  mybar(testvec, testelem) 32.570 35.6150 47.95297 37.9895 42.5220
705.267   100
 mybar2(testvec, testelem) 28.520 31.7695 45.36286 33.8250 37.7335
813.504   100
 mybar3(testvec, testelem)  9.449 25.0345 33.21592 26.2625 27.4070
635.800   100


On Mon, Dec 10, 2018 at 6:10 AM Serguei Sokol <serguei.sokol at gmail.com>
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20181211/323852ff/attachment.html>


More information about the Rcpp-devel mailing list