为什么 Rcpp::warning() 比 R 警告慢? [英] Why Rcpp::warning() is slower than R warning?

查看:41
本文介绍了为什么 Rcpp::warning() 比 R 警告慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下函数 foobar(仅打印警告不同)及其 R 等效函数 fooRbarR:

Consider the following functions foo and bar (differs only in printing warning) and their R equivalents fooR and barR:

cppFunction('
void foo () {
  int i = 0;
  while (i < 1e3) {
    i++;
  }
  return;
}')

cppFunction('
void bar () {
  int i = 0;
  while (i < 1e3) {
    i++;
    Rcpp::warning("hello world!");
  }
  return;
}')

fooR <- function() {
  i = 0;
  while (i < 1e3) {
    i = i+1;
  }
}

barR <- function() {
  i = 0;
  while (i < 1e3) {
    i = i+1;
    warning("hello world!")
  }
}

显然,打印警告会使函数变慢,但 R 和 Rcpp 之间的差异是巨大的(慢 200 倍 vs 慢 5000 倍!):

Obviously, printing warnings makes function slower, but the difference between R and Rcpp is huge (200 times slower vs 5000 times slower!):

> benchmark(foo(), bar())
   test replications elapsed relative user.self sys.self user.child sys.child
2 bar()          100   5.156     5156     5.156        0          0         0
1 foo()          100   0.001        1     0.000        0          0         0
There were 50 or more warnings (use warnings() to see the first 50)

> benchmark(fooR(), barR())
    test replications elapsed relative user.self sys.self user.child sys.child
2 barR()          100  11.102    213.5    11.104        0          0         0
1 fooR()          100   0.052      1.0     0.052        0          0         0
There were 50 or more warnings (use warnings() to see the first 50)

为什么会这样?可以预防吗?

Why is it so? Can it be prevented?

推荐答案

我不确定您是否从基准测试中意识到 Rcpp 是:

I'm not sure if you realize from your benchmark that Rcpp is:

  1. 11.102/5.156 = 发出警告的速度是 2.15322 倍
  2. 0.052/0.001 = 在纯循环情况下快 52 倍.

现在,当您在 Rcppbase R 中抛出警告时,会发生以下情况:

Now, when you are throwing a warning, in both Rcpp and base R, the following is occurring:

  1. 流到 STDERR 已打开.(因此,红色文本而不是 STDOUT 的黑色)
  2. 写留言
  3. 关闭STDERR
  4. 继续说明.
  1. Stream to STDERR is opened. (Hence, red text instead of STDOUT's black)
  2. Write message
  3. Close STDERR
  4. Continue instructions.

Rcpp 中,低级引用有助于降低重复上述过程并将控制返回到循环所花费的总时间,而 R 的处理程序位于堆栈较高的位置.

In Rcpp, the low-level reference helps lower the total amount of time it takes to repeat the above procedure and return control to the loop vs. R's handler that sits higher up on the stack.

同样,使用 Rcpp 完成此操作所需的时间是正常的,因为它必须将进程控制权交还给 R,打印消息,然后返回循环.考虑纯循环情况下速度损失的最佳方法是您决定在 C++ 循环中调用基于 R 的函数,而不是期望加速的 R 循环.

Again, the time it takes to complete this with Rcpp is normal as it has to cede control of the process back to R, print the message, then return to the loop. The best way to think about the loss of speed from the pure loop case is you decided to call an R based function in a C++ loop instead of an R loop expecting a speedup.

老实说,我有点惊讶 Rcpp 能够比等效的 R 快 2 倍.

To be honest, I'm a bit amazed that Rcpp was able to be 2x faster than the R equivalent.

这篇关于为什么 Rcpp::warning() 比 R 警告慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆