[Rcpp-devel] calling R function triggers tryCatch() ???

Romain Francois romain at r-enthusiasts.com
Fri Oct 11 17:04:03 CEST 2013


I will give some concretes next week. For now, i just wanted to hint: 
- mean is a mammoth. Try applying mean_ : 

mean_ <- function(.) .Internal(mean(.))

- by using x(r,_) you are allocating memory at each loop iteration, when we can use just one vector, since all rows are by definition of the same size. 

I will contribute code versions of these hints later. 

Romain

Le 11 oct. 2013 à 16:27, Hadley Wickham <h.wickham at gmail.com> a écrit :

> Interestingly, that shows that rowApply2 is actually slightly _slower_
> than rowApply1.
> 
> Hadley
> 
> On Fri, Oct 11, 2013 at 9:24 AM, Hadley Wickham <h.wickham at gmail.com> wrote:
>> FYI, I recommend using microbenchmark which uses a much higher
>> precision timer so you can see the variability as well as the mean
>> times. Also note that you can use /*** R */ to include R code that's
>> automatically run when benchmarking:
>> https://gist.github.com/hadley/6935459
>> 
>> That gives:
>> 
>>> microbenchmark(rowMeans(M),
>> +   apply(M, 1L, mean),
>> +   rowApply0(M, mean),
>> +   rowApply1(M, mean),
>> +   rowApply2(M, mean))
>> Unit: microseconds
>>              expr   min    lq median    uq   max neval
>>       rowMeans(M)  5.31  7.11   7.54  7.84  13.9   100
>> apply(M, 1L, mean) 46.23 49.46  50.78 53.06 136.9   100
>> rowApply0(M, mean) 50.87 53.81  55.36 57.54  85.3   100
>> rowApply1(M, mean) 18.92 20.14  21.20 22.44  36.9   100
>> rowApply2(M, mean) 18.73 20.18  21.27 22.40  34.0   100
>> 
>>> M <- matrix(rnorm(1500L), nrow=30L);
>> 
>>> microbenchmark(rowMeans(M),
>> +   apply(M, 1L, mean),
>> +   rowApply0(M, mean),
>> +   rowApply1(M, mean),
>> +   rowApply2(M, mean))
>> Unit: microseconds
>>              expr    min  lq median    uq    max neval
>>       rowMeans(M)   9.86  12     13  14.1   21.9   100
>> apply(M, 1L, mean) 265.28 288    308 349.8  475.2   100
>> rowApply0(M, mean) 506.54 541    575 604.9 5469.3   100
>> rowApply1(M, mean) 174.37 185    206 232.4  334.0   100
>> rowApply2(M, mean) 171.55 183    223 245.8 4244.7   100
>> 
>> On Fri, Oct 4, 2013 at 11:36 AM, Thomas Tse <tommy_228_228 at yahoo.com.hk> wrote:
>>> The next test compares the speeds:
>>> 
>>> // [[Rcpp::export]]
>>> NumericVector rowApply0(NumericMatrix& x, const Function& FUN)
>>> {
>>> int n = x.nrow();
>>> NumericVector result = no_init(n);
>>> 
>>> for (int r = 0; r < n; r++) {
>>>   result[r] = as<double>(FUN(x(r, _) ) );
>>> }
>>> return result;
>>> }
>>> 
>>> // [[Rcpp::export]]
>>> NumericVector rowApply1(NumericMatrix& x, const Function& FUN)
>>> {
>>> int n = x.nrow();
>>> NumericVector result = no_init(n);
>>> 
>>> for (int r = 0; r < n; r++) {
>>>   Language call(FUN, x(r, _)) ;
>>>   result[r] = as<double>(call.fast_eval() );
>>> }
>>> return result;
>>> }
>>> 
>>> // [[Rcpp::export]]
>>> NumericVector rowApply2(NumericMatrix& x, const Function& FUN)
>>> {
>>> int n = x.nrow();
>>> NumericVector result = no_init(n);
>>> 
>>> Language call(FUN, R_NilValue);
>>> Language::Proxy proxy(call, 1);
>>> for (int r = 0; r < n; r++) {
>>>   proxy = x(r, _) ;
>>>   result[r] = as<double>(call.fast_eval() );
>>> }
>>> return result;
>>> }
>>> 
>>>> M <- matrix(rnorm(15L), nrow=3L);
>>>> identical(rowMeans(M), apply(M, 1L, mean));
>>> [1] TRUE
>>>> identical(rowMeans(M), rowApply0(M, mean));
>>> [1] TRUE
>>>> identical(rowMeans(M), rowApply1(M, mean));
>>> [1] TRUE
>>>> identical(rowMeans(M), rowApply2(M, mean));
>>> [1] TRUE
>>>> benchmark(rowMeans(M),
>>> +           apply(M, 1L, mean),
>>> +           rowApply0(M, mean),
>>> +           rowApply1(M, mean),
>>> +           rowApply2(M, mean),
>>> +           replications=300000L);
>>>               test replications elapsed relative user.self sys.self
>>> user.child sys.child
>>> 3 rowApply0(M, mean)       300000   23.26    8.551     23.14        0
>>> NA        NA
>>> 2  apply(M, 1, mean)       300000   21.30    7.831     21.13        0
>>> NA        NA
>>> 4 rowApply1(M, mean)       300000   10.23    3.761     10.22        0
>>> NA        NA
>>> 5 rowApply2(M, mean)       300000    9.87    3.629      9.82        0
>>> NA        NA
>>> 1        rowMeans(M)       300000    2.72    1.000      2.72        0
>>> NA        NA
>>> 
>>>> M <- matrix(rnorm(1500L), nrow=30L);
>>>> benchmark(rowMeans(M),
>>> +           apply(M, 1L, mean),
>>> +           rowApply0(M, mean),
>>> +           rowApply1(M, mean),
>>> +           rowApply2(M, mean),
>>> +           replications=30000L);
>>>               test replications elapsed relative user.self sys.self
>>> user.child sys.child
>>> 3 rowApply0(M, mean)        30000   21.32   48.455     21.30        0
>>> NA        NA
>>> 2  apply(M, 1, mean)        30000   11.17   25.386     11.17        0
>>> NA        NA
>>> 4 rowApply1(M, mean)        30000    8.24   18.727      8.19        0
>>> NA        NA
>>> 5 rowApply2(M, mean)        30000    8.10   18.409      8.08        0
>>> NA        NA
>>> 1        rowMeans(M)        30000    0.44    1.000      0.43        0
>>> NA        NA
>>> 
>>>> M <- matrix(rnorm(150000L), nrow=300L);
>>>> benchmark(rowMeans(M),
>>> +           apply(M, 1L, mean),
>>> +           rowApply0(M, mean),
>>> +           rowApply1(M, mean),
>>> +           rowApply2(M, mean),
>>> +           replications=3000L);
>>>               test replications elapsed relative user.self sys.self
>>> user.child sys.child
>>> 3 rowApply0(M, mean)         3000   26.65   18.379     26.41     0.01
>>> NA        NA
>>> 2  apply(M, 1, mean)         3000   19.76   13.628     19.71     0.00
>>> NA        NA
>>> 4 rowApply1(M, mean)         3000   12.79    8.821     12.78     0.00
>>> NA        NA
>>> 5 rowApply2(M, mean)         3000   12.69    8.752     12.68     0.00
>>> NA        NA
>>> 1        rowMeans(M)         3000    1.45    1.000      1.45     0.00
>>> NA        NA
>>> 
>>> again, as Romain suggested, implementation rowApply2 is faster than
>>> rowApply1, and rowApply0 (which triggers tryCatch) is even slower than R's
>>> apply.
>>> 
>>> Thanks Romain !
>>> 
>>> 
>>> _______________________________________________
>>> 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
>> 
>> 
>> 
>> --
>> Chief Scientist, RStudio
>> http://had.co.nz/
> 
> 
> 
> -- 
> Chief Scientist, RStudio
> http://had.co.nz/
> _______________________________________________
> 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