Chào mừng đến với khóa học

Tối ưu hóa mã R với Rcpp

Romain François

Consulting Datactive, ThinkR

R so với C++

R

  • Tuyệt vời, linh hoạt
  • Chậm
  • Thông dịch

C++

  • Biên dịch
  • Khó hơn
  • Nhanh
Tối ưu hóa mã R với Rcpp

Động lực

  • Dùng Rcpp để tăng tốc mã của bạn
  • Không cần biết toàn bộ C++
  • Tập trung viết các hàm C++ đơn giản
Tối ưu hóa mã R với Rcpp

Cấu trúc khóa học

  • Giới thiệu - cú pháp C++ cơ bản
  • Hàm và luồng điều khiển trong C++
  • Lớp vector
  • Nghiên cứu tình huống
Tối ưu hóa mã R với Rcpp

Đo hiệu năng

phiên bản dùng vòng lặp của max

slowmax <- function(x){
   res <- x[1]
   for ( i in 2:length(x) ){
       if( x[i] > res ) res <- x[i]}
   res  }

So sánh hiệu năng với 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
Tối ưu hóa mã R với Rcpp
Tối ưu hóa mã R với Rcpp

Đánh giá các biểu thức C++ đơn giản với evalCpp

library(Rcpp)
evalCpp( "40 + 2" )
42
evalCpp( "exp(1.0)" )
2.718282
evalCpp( "sqrt(4.0)" )
2

Sử dụng

std::numeric_limits<int>::max()

để lấy số nguyên có dấu 32-bit (int) lớn nhất có thể biểu diễn

evalCpp(
   "std::numeric_limits<int>::max()"
   )
2147483647 

( $\footnotesize \mathtt{2147483647 = 2^{31}-1}$)

Tối ưu hóa mã R với Rcpp

Kiểu số cơ bản

C++ có bộ kiểu số phong phú

  • Số nguyên: int
  • Số thực dấu chấm động: double
Tối ưu hóa mã R với Rcpp

R

# Số literal là double
x <- 42
storage.mode(x)
"double"
# Số nguyên cần hậu tố L
y <- 42L
storage.mode(y)

z <- as.integer(42) storage.mode(z)
"integer"
"integer"

C++

# Hậu tố .0 ép thành double
y <- evalCpp( "42.0" )
storage.mode(y)
"double"
library(Rcpp)
# Số nguyên literal là int
x <- evalCpp( "42" )
storage.mode(x)
"integer"
Tối ưu hóa mã R với Rcpp

Ép kiểu

Ép kiểu tường minh với (double)

# Ép kiểu tường minh
y <- evalCpp("(double)(40 + 2)")
storage.mode(y)
"double"

Cẩn thận với phép chia số nguyên

# Chia số nguyên
evalCpp( "13 / 4" )
3

 

# Ép kiểu tường minh, do đó dùng 
# phép chia double
evalCpp( "(double)13 / 4" )
3.25

 

# Chuyển đổi tự động trong R
13L / 4L
3.25
Tối ưu hóa mã R với Rcpp

Cùng luyện tập nào!

Tối ưu hóa mã R với Rcpp

Preparing Video For Download...