Мій код повільний!

Ефективне програмування R

Colin Gillespie

Jumping Rivers & Newcastle University

Мій код справді повільний?

  • 1 секунда?
  • 1 хвилина?
  • 1 година?
Ефективне програмування R

Мій код справді повільний?

Ефективне програмування R

Бенчмаркування

  1. Обгорніть потрібну для бенчмаркування функціональність у функцію
  2. Виміряйте час у різних сценаріях, напр., розмір набору даних
Ефективне програмування R

Приклад: послідовність чисел

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

Варіант 1
1:n
Варіант 2
seq(1, n)
Варіант 3
seq(1, n, by = 1)
Ефективне програмування R

Обгортання у функції

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)
Ефективне програмування R

Вимірювання через 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 — це час ЦП, витрачений на виконання користувацьких інструкцій.
    • час system — це час ЦП, витрачений системою від імені процесу, що викликає.
    • час elapsed приблизно дорівнює сумі user і system; зазвичай нас цікавить саме він.
Ефективне програмування R

Збереження результату

Проблема з

system.time(colon(1e8))

у тому, що ми не зберегли результат. Треба перезапустити код і зберегти результат

res <- colon(1e8)

Оператор <- виконує обидві дії:

  • передавання аргументів
  • присвоєння обʼєкта
system.time(res <- colon(1e8))

Оператор = виконує лише одну з них:

  • передавання аргументів
  • присвоєння обʼєкта
# Спричиняє помилку
system.time(res = colon(1e8))
Ефективне програмування R

Відносний час

Method Absolute time (secs) Relative time
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$
Ефективне програмування R

Пакет microbenchmark

  • Порівнює функції
    • Кожну функцію запускають кілька разів
library("microbenchmark")

n <- 1e8 microbenchmark(colon(n), seq_default(n), seq_by(n), times = 10) # Запустити кожну функцію 10 разів
# 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
Ефективне програмування R

Давайте потренуємось!

Ефективне програмування R

Preparing Video For Download...