Это просто предоставило прекрасную возможность подключить Rcpp, который позволяет нам легко добавлять функции C ++ в R.
Итак, после небольшого исправления кода и использования пакетов inline (чтобы легко компилировать, загружать и связывать короткие фрагменты кода как динамически загружаемые функции), а также rbenchmark для измерения времени и сравнения функций, мы получаем потрясающий < / strong> 700-кратное увеличение производительности:
R> print(res)
test replications elapsed relative user.self sys.self
2 fibRcpp(N) 1 0.092 1.000 0.10 0
1 fibR(N) 1 65.693 714.054 65.66 0
R>
Здесь мы видим затраченное время 92 миллисекунды по сравнению с 65 секундами для относительного отношения 714. Но к настоящему времени все остальные сказали вам не делать это непосредственно в R .... Код ниже.
## inline to compile, load and link the C++ code
require(inline)
## we need a pure C/C++ function as the generated function
## will have a random identifier at the C++ level preventing
## us from direct recursive calls
incltxt <- '
int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}'
## now use the snipped above as well as one argument conversion
## in as well as out to provide Fibonacci numbers via C++
fibRcpp <- cxxfunction(signature(xs="int"),
plugin="Rcpp",
incl=incltxt,
body='
int x = Rcpp::as<int>(xs);
return Rcpp::wrap( fibonacci(x) );
')
## for comparison, the original (but repaired with 0/1 offsets)
fibR <- function(seq) {
if (seq == 0) return(0);
if (seq == 1) return(1);
return (fibR(seq - 1) + fibR(seq - 2));
}
## load rbenchmark to compare
library(rbenchmark)
N <- 35 ## same parameter as original post
res <- benchmark(fibR(N),
fibRcpp(N),
columns=c("test", "replications", "elapsed",
"relative", "user.self", "sys.self"),
order="relative",
replications=1)
print(res) ## show result
И для полноты, функции также производят правильный вывод:
R> sapply(1:10, fibR)
[1] 1 1 2 3 5 8 13 21 34 55
R> sapply(1:10, fibRcpp)
[1] 1 1 2 3 5 8 13 21 34 55
R>
person
Dirk Eddelbuettel
schedule
24.07.2011
1,2,3,5,8,...
, тогда как правильная последовательность -0,1,1,2,3,5,8,...
? - person Peter K.   schedule 24.07.2011gmp
имеет функциюfibnum
для вычисления чисел Фибоначчи с произвольной точностью. Со стандартнымdoubles
вы можете получить только доn=55
или около того. - person Ferdinand.kraft   schedule 17.06.2013