Codul meu este lent!

Scrierea codului R eficient

Colin Gillespie

Jumping Rivers & Newcastle University

Codul meu este cu adevărat lent?

  • 1 secundă?
  • 1 minut?
  • 1 oră?
Scrierea codului R eficient

Codul meu este cu adevărat lent?

Scrierea codului R eficient

Benchmarking

  1. Construim o funcție în jurul caracteristicii pe care dorim să o evaluăm
  2. Măsurăm timpul funcției în scenarii diferite, de ex., seturi de date
Scrierea codului R eficient

Exemplu: Secvență de numere

$$ 1, 2, 3, \ldots, n $$

Opțiunea 1
1:n
Opțiunea 2
seq(1, n)
Opțiunea 3
seq(1, n, by = 1)
Scrierea codului R eficient

Încapsularea funcțiilor

colon <- function(n) 1:n
colon(5)
1 2 3 4 5
seq_default <- function(n) seq(1, n)
seq_by <- function(n) seq(1, n, by = 1)
Scrierea codului R eficient

Măsurarea timpului cu system.time()

system.time(colon(1e8))
#   user  system elapsed
#  0.032   0.028   0.060
system.time(seq_default(1e8))
#   user  system elapsed
#  0.060   0.028   0.086
system.time(seq_by(1e8))
#   user  system elapsed
#  1.088   0.520   1.600
  • Timpul user este timpul CPU alocat execuției instrucțiunilor utilizatorului.
    • Timpul system este timpul CPU alocat execuției realizate de sistem în numele procesului apelant.
    • Timpul elapsed este aproximativ suma dintre user și system; acesta este valoarea care ne interesează de obicei.
Scrierea codului R eficient

Stocarea rezultatului

Problema cu

system.time(colon(1e8))

este că rezultatul nu este stocat. Trebuie să reexecutăm codul pentru a-l stoca:

res <- colon(1e8)

Operatorul <- realizează ambele operații:

  • Transmiterea argumentului
  • Atribuirea obiectului
system.time(res <- colon(1e8))

Operatorul = realizează una dintre:

  • Transmiterea argumentului
  • Atribuirea obiectului
# Raises an error
system.time(res = colon(1e8))
Scrierea codului R eficient

Timp relativ

Metodă Timp absolut (sec) Timp relativ
colon(n) 0.060 $0.060/0.060 = 1.00$
seq_default(n) 0.086 $0.086/0.060 = 1.40$
seq_by(n) 1.607 $1.60/0.060 = 26.7$
Scrierea codului R eficient

Pachetul microbenchmark

  • Compară funcții
    • Fiecare funcție este rulată de mai multe ori
library("microbenchmark")

n <- 1e8 microbenchmark(colon(n), seq_default(n), seq_by(n), times = 10) # Run each function 10 times
# Unit: milliseconds
#           expr  min   lq  mean  median   uq  max neval cld
#       colon(n)   59  130   220     202  341  391    10  a
# seq_default(n)   94  204   290     337  348  383    10  a
#      seq_by(n) 1945 2044  2260    2275 2359 2787    10   b
Scrierea codului R eficient

Să exersăm!

Scrierea codului R eficient

Preparing Video For Download...