Můj kód je pomalý!

Efektivní kód v R

Colin Gillespie

Jumping Rivers & Newcastle University

Je můj kód skutečně pomalý?

  • 1 sekunda?
  • 1 minuta?
  • 1 hodina?
Efektivní kód v R

Je můj kód skutečně pomalý?

Efektivní kód v R

Benchmarking

  1. Kolem testované funkcionality vytvoříme funkci
  2. Funkci změříme v různých scénářích, např. s různými datovými sadami
Efektivní kód v R

Příklad: Posloupnost čísel

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

Možnost 1
1:n
Možnost 2
seq(1, n)
Možnost 3
seq(1, n, by = 1)
Efektivní kód v R

Obalení funkcí

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)
Efektivní kód v R

Měření času pomocí 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
  • Čas user je čas CPU spotřebovaný při provádění uživatelských instrukcí.
    • Čas system je čas CPU spotřebovaný systémem jménem volajícího procesu.
    • Čas elapsed je přibližně součet user a system – toto číslo nás obvykle zajímá nejvíce.
Efektivní kód v R

Ukládání výsledku

Problém s

system.time(colon(1e8))

je, že výsledek není uložen. Je třeba kód spustit znovu a výsledek uložit:

res <- colon(1e8)

Operátor <- provádí oboje:

  • Předání argumentu
  • Přiřazení objektu
system.time(res <- colon(1e8))

Operátor = provádí jedno z:

  • Předání argumentu
  • Přiřazení objektu
# Raises an error
system.time(res = colon(1e8))
Efektivní kód v R

Relativní čas

Metoda Absolutní čas (s) Relativní čas
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$
Efektivní kód v R

Balíček microbenchmark

  • Porovnává funkce
    • Každá funkce je spuštěna vícekrát
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
Efektivní kód v R

Pojďme procvičovat!

Efektivní kód v R

Preparing Video For Download...