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

Hadley Wickham h.wickham at gmail.com
Fri Oct 11 16:24:41 CEST 2013


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/


More information about the Rcpp-devel mailing list