knitr::opts_chunk$set( comment = "#>", collapse = TRUE, cache = TRUE, fig.align="center", fig.pos="t" )
.Call is very painfullocal(source("code/07-performance_f5.R", local=TRUE))
install.packages("Rcpp")
efficientTutorial::test_rcpp()
## R version add_r = function(x, y) { return(x + y) }
/* Return type double * Two arguments, also doubles */ double add_c(double x, double y) { double value = x + y; return value; }
Exercise: What differences do you see?
main functionmain; not here. cppFunction commandlibrary("Rcpp") cppFunction(" double add_c(double x, double y){ double value = x + y; return value; } ")
Rcpp then performs magic!
add_c
We can call the add_c function in the usual way
add_c(1, 2)
vignette("rcpp", package="efficientTutorial")
Type | Description
------|-----------
char | A single character.
int | An integer.
float | A single precision floating point number.
double | A double-precision floating point number.
void | A valueless quantity.
There are also pointer's
cppFunction is great for small examples.cpp)sourceCpp("path/to/file.cpp").cpp needs a few headers.Cpp componentsAccess Rcpp functions (similar to a library call)
#include <Rcpp.h>
Rcpp::function_1Rcpp::
r
using namespace Rcpp;r
// [[Rcpp::export]]# include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] double add_c(double x, double y) { double value = x + y; return value; }
To save space, we'll omit the headers for the remainder of the chapter.
vignette("rcpp", package="efficientTutorial")
mean_rmean_r = function(x) { n = length(x) m = 0 for(i in seq_along(x)) m = m + x[i]/n m }
mean_cdouble mean_c(NumericVector x){ int i; int n = x.size(); double mean = 0; for(i=0; i<n; i++) { mean = mean + x[i]/n; } return mean; } sourceCpp("../src/mean_c.cpp")
cppFunction('double mean_c(NumericVector x){ int i; int n = x.size(); double mean = 0; for(i=0; i<n; i++) { mean = mean + x[i]/n; } return mean; }')
library("microbenchmark")
We generate some normal random numbers for the comparison
x = rnorm(1e4)
Then call the microbenchmark function.
z = microbenchmark( mean(x), mean_r(x), mean_c(x) )
par(mar=c(3,3,2,1), mgp=c(2,0.4,0), tck=-.01, cex.axis=0.9, las=1) boxplot(z, ylab="Time", col="steelblue") grid()
vignette("rcpp", package="efficientTutorial")
NumericVector res_c(NumericVector x, NumericVector y) { int i; int n = x.size(); NumericVector residuals(n); for(i=0; i<n; i++) { residuals[i] = pow(x[i] - y[i], 2); } return residuals; }
NumericVector res_sugar(NumericVector x, NumericVector y) { return pow(x - y, 2); }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.