R:Измерение времени выполнения выражений — различия между версиями

Материал Psylab.info - энциклопедии психодиагностики
Перейти к: навигация, поиск
м
Строка 9: Строка 9:
  
 
<syntaxhighlight lang="rsplus">
 
<syntaxhighlight lang="rsplus">
system.time(Sys.sleep(1))
+
> system.time(Sys.sleep(1))
 +
пользователь      система      прошло
 +
      0.003        0.004        1.000
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 17: Строка 19:
  
 
<syntaxhighlight lang="rsplus">
 
<syntaxhighlight lang="rsplus">
nvec <- rnorm(10^7L)
+
> x <- rnorm(10^7L)
</syntaxhighlight>
+
> system.time(mean(x))
 
+
пользователь      система      прошло
<syntaxhighlight lang="rsplus">
+
      0.020        0.000        0.022
system.time(mean(nvec))
+
> system.time(sum(x) / length(x))
system.time(sum(nvec) / length(nvec))
+
пользователь      система      прошло
 +
      0.013        0.000        0.013
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 38: Строка 41:
  
 
<syntaxhighlight lang="rsplus">
 
<syntaxhighlight lang="rsplus">
system.time(replicate(100, mean(nvec)))
+
> system.time(replicate(100, mean(x)))
system.time(replicate(100, sum(nvec) / length(nvec)))
+
пользователь      система      прошло
 +
      2.166        0.000        2.162
 +
> system.time(replicate(100, sum(x) / length(x)))
 +
пользователь      система      прошло
 +
      1.167        0.003        1.186
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 45: Строка 52:
  
 
<syntaxhighlight lang="rsplus">
 
<syntaxhighlight lang="rsplus">
system.time({
+
> system.time(for (i in seq_len(100)) mean(x))
  for (i in seq_len(100))
+
пользователь      система      прошло
    mean(nvec)
+
      2.110        0.003        2.126
})
+
> system.time(for (i in seq_len(100)) sum(x) / length(x))
system.time({
+
пользователь      система      прошло
  for (i in seq_len(100))
+
      1.070        0.000        1.085
    sum(nvec) / length(nvec)
+
})
+
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 58: Строка 63:
  
 
<syntaxhighlight lang="rsplus">
 
<syntaxhighlight lang="rsplus">
median(system.time(replicate(100, mean(nvec)))[["elapsed"]])
+
> median(system.time(replicate(100, mean(x)))[["elapsed"]])
 +
[1] 2.144
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Версия 19:09, 22 января 2014

Для измерения времени выполнения выражений используют следующие инструменты:

  • Функция Шаблон:Inline-code из базового пакета;
  • Cпециализированные функции (benchmarks, бенчмарки);
  • Функция профилирования времени выполнения кода Шаблон:Inline-code.

Функция system.time()

Самый простой инструмент для измерения времени выполнения кода - функция Шаблон:Inline-code из пакета Шаблон:Inline-code. В качестве аргумента функция Шаблон:Inline-code принимает выражения и возвращает время выполнения данного выражения. Измерим время выполнения функции Шаблон:Inline-code, которая останавливает выполнение кода на заданный интервал времени (в секундах):

<syntaxhighlight lang="rsplus"> > system.time(Sys.sleep(1)) пользователь система прошло

      0.003        0.004        1.000

</syntaxhighlight>

Как видим, на выполнение данной операции заняло ровно одну секунду.

Приведём ещё один пример. Сравним время вычисления встроенной в R функции (Шаблон:Inline-code) и среднего, вычисленного по формуле [math]\frac{1}{n}\sum_{i=1}^{n}x_{i}[/math]. на сгенерированном массиве нормально распределенных значений:

<syntaxhighlight lang="rsplus"> > x <- rnorm(10^7L) > system.time(mean(x)) пользователь система прошло

      0.020        0.000        0.022

> system.time(sum(x) / length(x)) пользователь система прошло

      0.013        0.000        0.013

</syntaxhighlight>

Функция возвращает 3 значения:

\end{itemize}

Соответственно, в выводе функции нас интересует значение Шаблон:Inline-code, который показывает время выполнения функции (выражения) в секундах. Как мы видим, внешне более сложное выражение Шаблон:Inline-code выполняется быстрее стандартной функции Шаблон:Inline-code.

К сожалению, подобный способ достаточно ненадежен, так как для оценки времени выполнения выражения функция Шаблон:Inline-code обращается к системным значениям времени. Следовательно, если во время выполнения кода параллельно производятся и другие операции на компьютере (а такое случается практически в ста процентах случаев), то возможно увеличение времени выполнения R-кода. Некоторую вариативность результатов можно увидеть, даже если выполнить функцию Шаблон:Inline-code несколько раз подряд. Подобной неточности оценки можно избежать путём многократного повторения выполняемых выражений и вычислением среднего времени, что позволит сгладить часть вариаций.

Базоый пакет позволяет реализовать процедуру многократного повторения выражения функции как минимум двумя способами. Первый - функция Шаблон:Inline-code. Приведенное выше сопоставление времени выполнения двух выражений при использовании функции Шаблон:Inline-code будет выглядеть следующим образом:

<syntaxhighlight lang="rsplus"> > system.time(replicate(100, mean(x))) пользователь система прошло

      2.166        0.000        2.162

> system.time(replicate(100, sum(x) / length(x))) пользователь система прошло

      1.167        0.003        1.186

</syntaxhighlight>

Тот же самый эффект можно получить и с помощью обычного цикла Шаблон:Inline-code:

<syntaxhighlight lang="rsplus"> > system.time(for (i in seq_len(100)) mean(x)) пользователь система прошло

      2.110        0.003        2.126

> system.time(for (i in seq_len(100)) sum(x) / length(x)) пользователь система прошло

      1.070        0.000        1.085

</syntaxhighlight>

Можно также использовать описательные статистики в сочетании с множественными повторениями:

<syntaxhighlight lang="rsplus"> > median(system.time(replicate(100, mean(x)))"elapsed") [1] 2.144 </syntaxhighlight>

В примере выше мы взяли только значения Шаблон:Inline-code и рассчитали медиану [1].

Вместо подобных решений можно использовать специальные пакеты, предназначенные для измерения производительности кода, в частности, пакеты Шаблон:Inline-code и Шаблон:Inline-code. Основной принцип работы этих пакетов заключается в многократном выполнении выражений и расчёта ряда интегральных показателей, в частности, суммы, среднего значения или медианы времени выполнения всех попыток.

Пакет rbenchmark

Пакет microbenchmark

Примечания

  1. Медиана является более устойчивой мерой центральной тенденции при асимметрии распределения, что, как правило, характерно для измерения времени.