[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 13:04:44 CET 2018
Small addendum: A large part of the performance gain in my example comes
from using NumericVector instead of std::vector<double>. Which avoids a
conversion. An example using std::copy with Numeric vector runs in the
same time as the version using memcpy.
Jan
On 10-12-18 12:28, Jan van der Laan wrote:
>
> 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
> _______________________________________________
> 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