Bem-vindo/a ao curso

Otimizando código R com Rcpp

Romain François

Consulting Datactive, ThinkR

R vs C++

R

  • Ótimo, flexível
  • Lento
  • Interpretado

C++

  • Compilado
  • Mais difícil
  • Rápido
Otimizando código R com Rcpp

Motivação

  • Use Rcpp para deixar seu código mais rápido
  • Não precisa saber todo o C++
  • Foque em escrever funções C++ simples
Otimizando código R com Rcpp

Estrutura do curso

  • Introdução — sintaxe básica de C++
  • Funções e controle de fluxo em C++
  • Classes de vetor
  • Estudos de caso
Otimizando código R com Rcpp

Medir desempenho

versão com loop de max

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

Comparando desempenho com 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
Otimizando código R com Rcpp
Otimizando código R com Rcpp

Avaliando expressões C++ simples com evalCpp

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

Usando

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

para obter o maior inteiro com sinal de 32 bits representável (int)

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

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

Otimizando código R com Rcpp

Tipos numéricos básicos

C++ tem um conjunto rico de tipos numéricos

  • Números inteiros: int
  • Ponto flutuante: double
Otimizando código R com Rcpp

R

# Literais numéricos são double
x <- 42
storage.mode(x)
"double"
# Inteiros precisam do sufixo L
y <- 42L
storage.mode(y)

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

C++

# Sufixo .0 força um double
y <- evalCpp( "42.0" )
storage.mode(y)
"double"
library(Rcpp)
# Literais inteiros são int
x <- evalCpp( "42" )
storage.mode(x)
"integer"
Otimizando código R com Rcpp

Casting

Conversão explícita com (double)

# Conversão explícita
y <- evalCpp("(double)(40 + 2)")
storage.mode(y)
"double"

Cuidado com a divisão inteira

# Divisão inteira
evalCpp( "13 / 4" )
3

 

# Conversão explícita e, assim,
# uso de divisão de double
evalCpp( "(double)13 / 4" )
3.25

 

# Conversão automática em R
13L / 4L
3.25
Otimizando código R com Rcpp

Vamos praticar!

Otimizando código R com Rcpp

Preparing Video For Download...