Важность векторизации кода

Эффективный код на R

Colin Gillespie

Jumping Rivers & Newcastle University

Общее правило

  • Вызов функции R в конечном счёте приводит к коду на C или FORTRAN
    • Этот код очень тщательно оптимизирован

Цель

  • Обращаться к коду C или FORTRAN как можно быстрее; чем меньше вызовов функций — тем лучше.
Эффективный код на R

Векторизованные функции

  • Многие функции R векторизованы
    • Принимают одно число, но возвращают вектор
rnorm(4)
-0.7247  0.2502  0.3510  0.6919
  • Принимают вектор на вход
mean(c(36, 48))
42
Эффективный код на R

Генерация случайных чисел

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

Сравните

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

с

x <- rnorm(n)
Эффективный код на R

Почему цикл работает медленно?

Цикл
x <- vector("numeric", n)
for(i in seq_along(x))
    x[i] <- rnorm(1)
Выделение памяти
x <- vector("numeric", n)
  • Цикл: разовые затраты
  • Векторизация: сопоставимые
Генерация
  • Цикл: миллион вызовов rnorm()
  • Векторизация: один вызов rnorm()
Присваивание
  • Цикл: миллион вызовов метода присваивания
  • Векторизация: одно присваивание
Эффективный код на R

R-клуб

Второе правило R-клуба: используйте векторизованное решение везде, где это возможно.

Эффективный код на R

Давайте потренируемся!

Эффективный код на R

Preparing Video For Download...