과정 소개

Rcpp로 R 코드 최적화하기

Romain François

Consulting Datactive, ThinkR

R vs 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

# Literal numbers are double
x <- 42
storage.mode(x)
"double"
# Integers need the L suffix
y <- 42L
storage.mode(y)

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

C++

# Suffix .0 forces a double
y <- evalCpp( "42.0" )
storage.mode(y)
"double"
library(Rcpp)
# Literal integers are int
x <- evalCpp( "42" )
storage.mode(x)
"integer"
Rcpp로 R 코드 최적화하기

형변환

(double)을 사용한 명시적 형변환

# Explicit cast
y <- evalCpp("(double)(40 + 2)")
storage.mode(y)
"double"

정수 나눗셈에 주의하세요

# Integer division
evalCpp( "13 / 4" )
3

 

# Explicit cast, and hence use 
# of double division
evalCpp( "(double)13 / 4" )
3.25

 

# Automatic conversion in R
13L / 4L
3.25
Rcpp로 R 코드 최적화하기

연습해 봅시다!

Rcpp로 R 코드 최적화하기

Preparing Video For Download...