歡迎加入本課程

用 Rcpp 最佳化 R 程式碼

Romain François

Consulting Datactive, ThinkR

R 與 C++

R

  • 強大、彈性高
  • 較慢
  • 直譯式

C++

  • 編譯式
  • 較難
  • 很快
用 Rcpp 最佳化 R 程式碼

學習動機

  • 用 Rcpp 讓程式碼更快
  • 不必精通整個 C++
  • 專注撰寫簡單的 C++ 函式
用 Rcpp 最佳化 R 程式碼

課程結構

  • 介紹:基本 C++ 語法
  • C++ 函式與控制流程
  • 向量類別
  • 案例研究
用 Rcpp 最佳化 R 程式碼

量測效能

以迴圈實作的 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
用 Rcpp 最佳化 R 程式碼
用 Rcpp 最佳化 R 程式碼

用 evalCpp 評估簡單的 C++ 運算式

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}$)

用 Rcpp 最佳化 R 程式碼

基本數值型別

C++ 有豐富的數值型別

  • 整數:int
  • 浮點數:double
用 Rcpp 最佳化 R 程式碼

R

# 常值數字為 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"
用 Rcpp 最佳化 R 程式碼

型別轉換(Casting)

(double) 進行顯式轉型

# 顯式轉型
y <- evalCpp("(double)(40 + 2)")
storage.mode(y)
"double"

留意整數除法

# 整數除法
evalCpp( "13 / 4" )
3

 

# 顯式轉型,因此使用
# double 的除法
evalCpp( "(double)13 / 4" )
3.25

 

# R 中的自動轉型
13L / 4L
3.25
用 Rcpp 最佳化 R 程式碼

一起來練習吧!

用 Rcpp 最佳化 R 程式碼

Preparing Video For Download...