用 Rcpp 优化 R 代码
Romain François
Consulting Datactive, ThinkR
R
C++
max 的循环版本
slowmax <- function(x){
res <- x[1]
for ( i in 2:length(x) ){
if( x[i] > res ) res <- x[i]}
res }
使用 microbenchmark 比较性能
library(microbenchmark)
x <- rnorm(1e6)
microbenchmark( slowmax(x), max(x) )
Unit: milliseconds
expr min lq mean median uq max neval
slowmax(x) 31.649452 34.29454 36.344912 35.435299 37.188249 90.363038 100
max(x) 1.563559 1.74036 1.939367 1.847045 2.014684 3.340052 100
library(Rcpp)
evalCpp( "40 + 2" )
42
evalCpp( "exp(1.0)" )
2.718282
evalCpp( "sqrt(4.0)" )
2
使用
std::numeric_limits<int>::max()
获取 32 位有符号整数(int)的最大值
evalCpp(
"std::numeric_limits<int>::max()"
)
2147483647
( $\footnotesize \mathtt{2147483647 = 2^{31}-1}$)
C++ 拥有丰富的数值类型
intdoubleR
# 字面量数字为 double
x <- 42
storage.mode(x)
"double"
# 整数需加后缀 L y <- 42L storage.mode(y)z <- as.integer(42) storage.mode(z)
"integer"
"integer"
C++
# 后缀 .0 强制为 double
y <- evalCpp( "42.0" )
storage.mode(y)
"double"
library(Rcpp)
# 字面量整数为 int
x <- evalCpp( "42" )
storage.mode(x)
"integer"
使用 (double) 显式类型转换
# 显式转换
y <- evalCpp("(double)(40 + 2)")
storage.mode(y)
"double"
注意整数除法
# 整数除法
evalCpp( "13 / 4" )
3
# 显式转换,因此使用
# 浮点除法
evalCpp( "(double)13 / 4" )
3.25
# R 中的自动转换
13L / 4L
3.25
用 Rcpp 优化 R 代码