Rcpp上的等式逻辑运算符比基数R慢8倍

看下面简单的代码和操作:

    library(Rcpp)
    library(microbenchmark)

    set.seed(100)
    x <- sample(0:1, 1000000, replace = TRUE)
    y <- sample(0:1, 1000000, replace = TRUE)
    
    cppFunction('LogicalVector is_equal_c(NumericVector x, NumericVector y) {
      return x == y;
    }')
    is_equal_R <- function(x, y) {
      return(x==y)
    }
    mbm <- microbenchmark(c = is_equal_c(x,y),
                          R = is_equal_R(x,y)
    )
    mbm

它给出了以下执行速度的性能:

Unit: milliseconds
 expr    min     lq      mean  median       uq      max neval cld
    c 6.4132 6.6896 10.961774 11.2421 12.63245 102.5480   100   b
    R 1.2555 1.2994  1.766561  1.3327  1.38220   9.0022   100  a 

简单的 R 相等运算符比 Rcpp 快 8 倍。为什么会这样,有没有办法使 Rcpp 代码至少与 R 简单向量相等运算符一样快?

回答

正如弗洛里安已经暗示的那样,通过强制从intto复制一个昂贵的副本,错误是你的numeric

> class(1:3)
[1] "integer"
> class(1:3 + 0)   # Florian's conversion
[1] "numeric"
> 

因为整数值实际上比数字“更轻”(在 32 位和 64 位),我们不妨坚持使用整数并相应地修改您的 C++ 函数签名

在我的计算机上,C++ 击败了 R,但两者都是 vrey 代码,正如您对 R 中已经向量化的实现所期望的那样。

修改代码

现在作为带有嵌入式 R 代码的 C++ 文件

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::LogicalVector is_equal_c(Rcpp::IntegerVector x, Rcpp::IntegerVector y) {
  return x == y;
}

/*** R
library(microbenchmark)

set.seed(100)
x <- sample(0:1, 1000000, replace = TRUE)
y <- sample(0:1, 1000000, replace = TRUE)

is_equal_R <- function(x, y) {
  return(x==y)
}
mbm <- microbenchmark(c = is_equal_c(x,y),
                      R = is_equal_R(x,y))
mbm
*/

输出

> Rcpp::sourceCpp("answer.cpp")

> library(microbenchmark)

> set.seed(100)

> x <- sample(0:1, 1000000, replace = TRUE)

> y <- sample(0:1, 1000000, replace = TRUE)

> is_equal_R <- function(x, y) {
+ > return(x==y)
+ > 
}

> mbm <- microbenchmark(c = is_equal_c(x,y),
+ >                     R = is_equal_R(x,y))

> mbm
Unit: milliseconds
 expr     min      lq    mean  median      uq      max neval cld
    c 1.77923 1.82570 2.06075 1.87093 1.93911  4.31854   100   a
    R 1.20529 2.03077 2.23089 2.06222 2.11870 10.89118   100   a
> 

所以总而言之,你的结果是那些让人头疼的人之一,“这不可能是真的......”,这些都是非常好的学习经验:)


以上是Rcpp上的等式逻辑运算符比基数R慢8倍的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>