简体   繁体   中英

Why is this Rcpp code not faster than pure R?

I tried some R and Rcpp benchmarks with Fibonacci numbers:

in pure R:

 fibR <- function(n) {
     if (n < 2)
        n
     else
        fib(n - 1) + fib(n - 2)
 }

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:

library(rbenchmark)

benchmark(fib(30), fibR(30))[,1:3]

# results:

      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]

# results:

      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]

# results

      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 is this so, 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.

Code

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]

Output

         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 directoryexamples/Misc/ in your Rcpp installation for examples last updated years ago. Also look at prior questions here on SO .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM