【问题标题】:Why is this Rcpp code not faster than pure R?为什么这个 Rcpp 代码不比纯 R 快?
【发布时间】:2021-09-29 20:36:23
【问题描述】:

设置

我用斐波那契数尝试了一些 R 和 Rcpp 基准测试。

纯R

我们将fibR 函数用于纯R 编写的代码。

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

Rcpp

我们使用另一个fib 函数来编写Rcpp 中的代码。

library(Rcpp)

Rcpp::cppFunction('int fib(int x) {
    if((x < 2)) 
       return(x);
    else 
       return(fib(x-1) + fib(x-2));
   }')

结果

这是根据几个基准测试的结果。

library(rbenchmark)

在那之后,我做了几个测试。

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

我希望 Rcpp 代码比等效的 R 代码稳定地快,但不,它有时会更慢!

为什么它会这样工作,我错过了什么?

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    当某些事情不属实时,您应该仔细检查发生了什么:)

    这里您的 R 函数调用了您的 C++ 函数,因为您不注意 fib() 的来源。接下来是修复后的更明确的版本。

    代码

    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
    

    这是一个经过充分研究的示例。查看 Rcpp 安装中的目录 examples/Misc/ 以获取几年前最后更新的示例。也可以看看prior questions here on SO

    【讨论】:

      猜你喜欢
      • 2015-03-26
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      • 2011-08-22
      • 2023-03-05
      • 2014-11-10
      • 1970-01-01
      相关资源
      最近更新 更多