Vikten av att vektorisera din kod

Effektiv R-kod

Colin Gillespie

Jumping Rivers & Newcastle University

Grundregel

  • Att anropa en R-funktion leder slutligen till C- eller FORTRAN-kod
    • Denna kod är mycket hårt optimerad

Mål

  • Nå den underliggande C- eller FORTRAN-koden så snabbt som möjligt – ju färre funktionsanrop desto bättre.
Effektiv R-kod

Vektoriserade funktioner

  • Många R-funktioner är vektoriserade
    • Enstaka tal men returnerar en vektor
rnorm(4)
-0.7247  0.2502  0.3510  0.6919
  • Vektor som indata
mean(c(36, 48))
42
Effektiv R-kod

Generera slumptal

library(microbenchmark)
n <- 1e6
x <- vector("numeric", n)
microbenchmark(
    x <- rnorm(n),
    {
        for(i in seq_along(x))
            x[i] <- rnorm(1)
        },
    times = 10
)
# Unit: milliseconds
# expr        lq mean    uq  cld
# rnorm(n)    60   70    80  a
# Looping   2600 2700  2800   b

## Output trimmed for presentation

Jämför

x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)

med

x <- rnorm(n)
Effektiv R-kod

Varför är loopen långsam?

Loopning
x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)
Allokering
x <- vector("numeric", n)
  • Loop: Engångskostnad
  • Vektoriserad: Jämförbar
Generering
  • Loop: En miljon anrop till rnorm()
  • Vektoriserad: Ett enda anrop till rnorm()
Tilldelning
  • Loop: En miljon anrop till tilldelningsmetoden
  • Vektoriserad: En enda tilldelning
Effektiv R-kod

R-klubben

Den andra regeln i R-klubben: använd en vektoriserad lösning när det är möjligt.

Effektiv R-kod

Nu kör vi en övning!

Effektiv R-kod

Preparing Video For Download...