<- function(n) {
fib if(n == 0) return(0)
if(n == 1) return(1)
Recall(n - 1) + Recall(n - 2)
}
Writing C++ in R with Rcpp
Sometimes, parallelization is not an option, either because the code is hard to parallelize or because of lack of hardware. In such cases, one way to increase speed is to replace slow R code with C++. The package Rcpp makes this particularly easy by creating mappings between both languages.
Back to Fibonacci
Do you remember the Fibonacci numbers? Here was a naive implementation in R:
This function gives the nth number in the sequence.
Example:
fib(30)
[1] 832040
Rcpp
Let’s translate this function in C++ within R!
First we need to load the Rcpp package:
library(Rcpp)
We then use the function cppFunction()
to assign to an R function a function written in C++:
<- cppFunction( '
fibRcpp int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}
' )
We can call our function as any R function:
fibRcpp(30)
[1] 832040
We can compare both functions:
library(bench)
<- 30
n mark(fib(n), fibRcpp(n))
# A tibble: 2 × 13
expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>
1 fib(n) 1.66s 1.66s 0.601 44.7KB 22.8 1 38
2 fibRcpp(n) 1.08ms 1.08ms 901. 2.49KB 0 451 0
total_time result memory time
<bch:tm> <list> <list> <list>
1 1.66s <dbl [1]> <Rprofmem [6,778 × 3]> <bench_tm [1]>
2 500.37ms <int [1]> <Rprofmem [1 × 3]> <bench_tm [451]>
gc
<list>
1 <tibble [1 × 3]>
2 <tibble [451 × 3]>
Warning message:
Some expressions had a GC in every iteration; so filtering is disabled.
The speedup is 1,537, which is amazing.
In this particular example, we saw that memoisation gives an even more incredible speedup (35,000!), but while memoisation will only work in very specific situations (e.g. recursive function calls), using C++ code is a general method to provide speedup. It is particularly useful when:
- there are large numbers of function calls (R is particularly slow with function calls),
- you need data structures that are missing in R,
- you want to create efficient packages (fast R packages are written in C++ and many use Rcpp).
In this example, we declared the C++ function directly in R. It is possible to use source files instead.