I tried some R and Rcpp benchmarks with Fibonacci numbers.
We use the fibR
function for the code that was written in pure R.
fibR <- function(n) {
if (n < 2)
n
else
fib(n - 1) + fib(n - 2)
}
We use another fib
function for the code written in Rcpp.
library(Rcpp)
Rcpp::cppFunction('int fib(int x) {
if((x < 2))
return(x);
else
return(fib(x-1) + fib(x-2));
}')
Here are the results according to several benchmarks tests.
library(rbenchmark)
After that, I did several tests.
benchmark(fib(30), fibR(30))[,1:3]
test replications elapsed
1 fib(30) 100 0.46
2 fibR(30) 100 0.45
benchmark(fib(31), fibR(31))[,1:3]
test replications elapsed
1 fib(31) 100 0.77
2 fibR(31) 100 0.80
benchmark(fib(32), fibR(32))[,1:3]
test replications elapsed
1 fib(32) 100 1.37
2 fibR(32) 100 1.33
benchmark(fib(33), fibR(33))[,1:3]
test replications elapsed
1 fib(33) 100 1.88
2 fibR(33) 100 2.02
benchmark(fib(34), fibR(34))[,1:3]
test replications elapsed
1 fib(34) 100 3.09
2 fibR(34) 100 3.26
benchmark(fib(35), fibR(35))[,1:3]
test replications elapsed
1 fib(35) 100 5.57
2 fibR(35) 100 5.60
benchmark(fib(36), fibR(36))[,1:3]
test replications elapsed
1 fib(36) 100 8.95
2 fibR(36) 100 8.51
benchmark(fib(37), fibR(37))[,1:3]
test replications elapsed
1 fib(37) 100 16.94
2 fibR(37) 100 14.47
benchmark(fib(38), fibR(38))[,1:3]
test replications elapsed
1 fib(38) 100 22.92
2 fibR(38) 100 23.67
benchmark(fib(39), fibR(39))[,1:3]
test replications elapsed
1 fib(39) 100 35.80
2 fibR(39) 100 38.83
I would expect that the Rcpp code is steadily faster than the equivalent R code, but no – it is sometimes slower!
Why does it work like this, and what am I missing?
When something can't be true you should check closely what is going on :)
Here your R function called your C++ function as you were not careful about where fib()
was coming from. A repaired, more explicit version follow.
fibR <- function(n) {
if (n < 2)
n
else
fibR(n - 1) + fibR(n - 2)
}
library(Rcpp)
Rcpp::cppFunction('int fibRcpp(int x) {
if ((x < 2))
return(x);
else
return(fibRcpp(x-1) + fibRcpp(x-2));
}')
library(rbenchmark)
benchmark(fibRcpp(30), fibR(30))[,1:3]
test replications elapsed
2 fibR(30) 100 80.846
1 fibRcpp(30) 100 0.153
This is a rather well-studied example. Look at the directory examples/Misc/ in your Rcpp installation for examples last updated years ago. Also look at prior questions here on SO.