【问题标题】:Why is this simplistic cpp function version slower?为什么这个简单的 cpp 函数版本变慢了?
【发布时间】:2016-09-28 20:48:01
【问题描述】:

考虑这个比较:

require(Rcpp)
require(microbenchmark)

cppFunction('int cppFun (int x) {return x;}')
RFun = function(x) x

x=as.integer(2)
microbenchmark(RFun=RFun(x),cppFun=cppFun(x),times=1e5)

Unit: nanoseconds
   expr  min   lq      mean median   uq      max neval cld
   RFun  302  357  470.2047    449  513   110152 1e+06  a 
 cppFun 2330 2598 4045.0059   2729 2879 68752603 1e+06   b

cppFun 似乎比RFun 慢。为什么会这样?调用函数的时间是否不同?或者是运行时间不同的函数本身?是时候传递和返回参数了吗?是否有一些我不知道的数据转换或数据复制何时将数据传递到(或返回)cppFun

【问题讨论】:

  • 外函数接口有开销,这不足为奇。当你的函数开始做一些真正有用的工作时,你可能永远不会注意到开销。但是现在你的函数除了开销之外没有任何成本。
  • 想象你是 R 并且 CPP 是你勤奋的同事。更快的是:立即重复对您说过的任何一句话,或者走到您的同事身边并让他们为您做这件事?现在,把“重复一句话”改成“做纳税申报”,事情可能会变得不同。 (免责声明:我从未尝试在 C++ 中进行纳税申报。它可能更快,但也可能比在 R 中更复杂。)
  • @JeroenMostert 作为一名博士生,我的纳税申报表很容易处理;)谢谢你的比喻!
  • @Remi.b:我期待您更快地实施。完成后,您是否介意在时间机器和perpertuum mobile 上工作?
  • @DirkEddelbuettel 哼...我不明白这种讽刺的原因。你的意思是我在 cmets 的跟进太广泛了? (我已经将 Rcpp 用于更复杂的过程,我只是想知道多次调用 cpp 函数是否会付出代价)。

标签: r performance function benchmarking rcpp


【解决方案1】:

正如上面的 cmets 所示,这根本不是一个精心设计或深思熟虑的问题。

空函数的假设基线根本不是一个。通过cppFunction() 等创建的每个函数都将调用一个R 函数某个C++ 函数 接口。所以这根本不可能相等。

这是一个更有意义的比较。首先,让我们用花括号来完成 R 函数。其次,让我们调用另一个编译器(内部)函数:

require(Rcpp)
require(microbenchmark)

cppFunction('int cppFun (int x) {return x;}')
RFun1 <- function(x) { x }
RFun2 <- function(x) { .Primitive("abs")(x) }

print(microbenchmark(RFun1(2L), RFun2(2L), cppFun(2L), times=1e5))

在我的盒子上,我看到 a) 版本 1 和 2(或 C++ 函数)之间的差距更小,b) 对内部函数的惩罚很小。 但是从 R 调用任何编译的函数都是有代价的。

Unit: nanoseconds
       expr min   lq     mean median   uq     max neval
  RFun1(2L) 171  338  434.136    355  408 2659984 1e+05
  RFun2(2L) 683  937 1334.046   1257 1341 7605628 1e+05
 cppFun(2L) 721 1131 1416.091   1239 1385 8544656 1e+05

正如我们在现实世界中所说:没有免费的午餐。

【讨论】:

  • 哦,这完全有道理。这是 @BenVoigt 在 cmets 中所指的“开销”吗?谢谢
  • 是的,除其他外。 cppFun()RFun2() 实际上有一个带有要执行的代码的主体。 RFun1() 没有。他们怎么可能在运行时相等?在尝试测量“空”时,您还犯了一个新手分析错误。这确实没有太大意义。
  • 好的,我认为这对我来说很有意义 +1。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-08-27
相关资源
最近更新 更多