Min kod är långsam!

Effektiv R-kod

Colin Gillespie

Jumping Rivers & Newcastle University

Är min kod verkligen långsam?

  • 1 sekund?
  • 1 minut?
  • 1 timme?
Effektiv R-kod

Är min kod verkligen långsam?

Effektiv R-kod

Benchmarking

  1. Vi skapar en funktion kring det vi vill benchmarka
  2. Vi tidsmäter funktionen under olika scenarier, t.ex. datamängd
Effektiv R-kod

Exempel: Talföljd

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

Alternativ 1
1:n
Alternativ 2
seq(1, n)
Alternativ 3
seq(1, n, by = 1)
Effektiv R-kod

Omslutning med funktion

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)
Effektiv R-kod

Tidmätning med 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
  • user-tid är den CPU-tid som räknas för användarinstruktioner.
    • system-tid är den CPU-tid som räknas för systemanrop på processens vägnar.
    • elapsed-tid är ungefär summan av user och system – det här är värdet vi normalt bryr oss om.
Effektiv R-kod

Lagra resultatet

Problemet med

system.time(colon(1e8))

är att resultatet inte sparas. Vi måste köra om koden för att lagra resultatet

res <- colon(1e8)

Operatorn <- utför båda:

  • Argumentöverföring
  • Objekttilldelning
system.time(res <- colon(1e8))

Operatorn = utför en av:

  • Argumentöverföring
  • Objekttilldelning
# Raises an error
system.time(res = colon(1e8))
Effektiv R-kod

Relativ tid

Metod Absolut tid (sek) Relativ tid
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$
Effektiv R-kod

Paketet microbenchmark

  • Jämför funktioner
    • Varje funktion körs flera gånger
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
Effektiv R-kod

Nu kör vi en övning!

Effektiv R-kod

Preparing Video For Download...