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_1
Rcpp::
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_r
mean_r = function(x) { n = length(x) m = 0 for(i in seq_along(x)) m = m + x[i]/n m }
mean_c
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; } 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.