[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