Hi, The following code shows that inline function is over 10 times faster than .Call and calling .Call directly is slower than call .Call by wrapping it in another function. Is this expected?
~/dvcs_src/rexample/Rexample/cran/inline/cxxfunction/dyn.load$ cat test.cpp #include <Rcpp.h> RcppExport SEXP test(SEXP bold_eta_theta) { using namespace Rcpp; NumericMatrix x(bold_eta_theta); NumericMatrix result(x.nrow(), x.ncol()+1); for(unsigned i = 0; i < x.nrow(); ++ i) { double row_max=0; for(unsigned j = 0; j < x.ncol(); ++ j) { if(x(i, j) > row_max) row_max = x(i, j); } double row_exp_sum=0; for(unsigned j = 0; j < x.ncol(); ++ j) { double tmp = exp(x(i, j) - row_max); result(i,j) = tmp; row_exp_sum += tmp; } double tmp = exp(-row_max); result(i, x.ncol()) = tmp; row_exp_sum += tmp; for(unsigned j = 0; j < result.ncol(); ++ j) { result(i,j) /= row_exp_sum; } } return wrap(result); } ~/dvcs_src/rexample/Rexample/cran/inline/cxxfunction/dyn.load$ cat main.R dyn.load('test.so') test=function(xx) { .Call('test', xx) } suppressPackageStartupMessages(library(inline)) test_inline=cxxfunction( signature(xx='numeric') , body=' Rcpp::NumericMatrix x(xx); Rcpp::NumericMatrix result(x.nrow(), x.ncol()+1); for(unsigned i = 0; i < x.nrow(); ++ i) { double row_max=0; for(unsigned j = 0; j < x.ncol(); ++ j) { if(x(i, j) > row_max) row_max = x(i, j); } double row_exp_sum=0; for(unsigned j = 0; j < x.ncol(); ++ j) { double tmp = exp(x(i, j) - row_max); result(i,j) = tmp; row_exp_sum += tmp; } double tmp = exp(-row_max); result(i, x.ncol()) = tmp; row_exp_sum += tmp; for(unsigned j = 0; j < result.ncol(); ++ j) { result(i,j) /= row_exp_sum; } } return wrap(result); ' , plugin='Rcpp' ) xx=matrix(1:6, nrow=2) library(microbenchmark) microbenchmark(test(xx)) microbenchmark(test_inline(xx)) microbenchmark(.Call('test', xx)) ~/dvcs_src/rexample/Rexample/cran/inline/cxxfunction/dyn.load$ Rscript main.R > dyn.load('test.so') > test=function(xx) { + .Call('test', xx) + } > > suppressPackageStartupMessages(library(inline)) > test_inline=cxxfunction( + signature(xx='numeric') + , body=' + Rcpp::NumericMatrix x(xx); + Rcpp::NumericMatrix result(x.nrow(), x.ncol()+1); + + for(unsigned i = 0; i < x.nrow(); ++ i) { + double row_max=0; + for(unsigned j = 0; j < x.ncol(); ++ j) { + if(x(i, j) > row_max) row_max = x(i, j); + } + double row_exp_sum=0; + for(unsigned j = 0; j < x.ncol(); ++ j) { + double tmp = exp(x(i, j) - row_max); + result(i,j) = tmp; + row_exp_sum += tmp; + } + double tmp = exp(-row_max); + result(i, x.ncol()) = tmp; + row_exp_sum += tmp; + + for(unsigned j = 0; j < result.ncol(); ++ j) { + result(i,j) /= row_exp_sum; + } + } + return wrap(result); + ' + , plugin='Rcpp' + ) > > > xx=matrix(1:6, nrow=2) > > library(microbenchmark) > microbenchmark(test(xx)) Unit: microseconds expr min lq median uq max 1 test(xx) 69.51999999999999602096 70.02899999999999636202 72.79200000000000159162 73.49150000000000204636 196.9259999999999877218 > microbenchmark(test_inline(xx)) Unit: microseconds expr min lq median uq max 1 test_inline(xx) 4.413999999999999701572 4.633000000000000007105 4.749500000000000277112 4.894000000000000127898 74.78600000000000136424 > microbenchmark(.Call('test', xx)) Unit: microseconds expr min lq median uq max 1 .Call("test", xx) 95.9890000000000043201 96.81999999999999317879 100.1795000000000044338 101.0649999999999977263 211.9449999999999931788 > > -- Regards, Peng _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel