Изменения

R:Измерение времени выполнения выражений

6706 байтов добавлено, 15:51, 22 января 2014
Новая страница: «Для измерения времени выполнения выражений используют следующие инструменты: * Функция …»
Для измерения времени выполнения выражений используют следующие инструменты:
* Функция {{Inline-code|system.time()|lang=rsplus}} из базового пакета;
* Cпециализированные функции (benchmarks, бенчмарки);
* Функция профилирования времени выполнения кода {{Inline-code|Rprof()|lang=rsplus}}.

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

Самый простой инструмент для измерения времени выполнения кода --- функция {{Inline-code|system.time()|lang=rsplus}} из пакета {{Inline-code|base|lang=rsplus}}. В качестве аргумента функция {{Inline-code|system.time()|lang=rsplus}} принимает выражения и возвращает время выполнения данного выражения. Измерим время выполнения функции {{Inline-code|Sys.sleep()|lang=rsplus}}, которая останавливает выполнение кода на заданный интервал времени (в секундах):

<syntaxhighlight lang="rsplus">
system.time(Sys.sleep(1))
</syntaxhighlight>

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

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

<syntaxhighlight lang="rsplus">
nvec <- rnorm(10^7L)
</syntaxhighlight>

<syntaxhighlight lang="rsplus">
system.time(mean(nvec))
system.time(sum(nvec) / length(nvec))
</syntaxhighlight>

Функция возвращает 3 значения:
* {{Inline-code|user|lang=rsplus}} --- время CPU, которое занял пользователь;
* {{Inline-code|system|lang=rsplus}} --- время CPU, которое заняла система;
* {{Inline-code|elapsed|lang=rsplus}} --- реальное время, которое заняло выполнение команды.
\end{itemize}

Соответственно, в выводе функции нас интересует значение {{Inline-code|elapsed|lang=rsplus}}, который показывает время выполнения функции (выражения) в секундах. Как мы видим, внешне более сложное выражение {{Inline-code|sum(x) / length(x)|lang=rsplus}} выполняется быстрее стандартной функции {{Inline-code|mean(x)|lang=rsplus}}.

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

Базоый пакет позволяет реализовать процедуру многократного повторения выражения функции как минимум двумя способами. Первый --- функция {{Inline-code|replicate()|lang=rsplus}}. Приведенное выше сопоставление времени выполнения двух выражений при использовании функции {{Inline-code|replicate()|lang=rsplus}} будет выглядеть следующим образом:

<syntaxhighlight lang="rsplus">
system.time(replicate(100, mean(nvec)))
system.time(replicate(100, sum(nvec) / length(nvec)))
</syntaxhighlight>

Тот же самый эффект можно получить и с помощью обычного цикла {{Inline-code|for()|lang=rsplus}}:

<syntaxhighlight lang="rsplus">
system.time({
for (i in seq_len(100))
mean(nvec)
})
system.time({
for (i in seq_len(100))
sum(nvec) / length(nvec)
})
</syntaxhighlight>

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

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

В примере выше мы взяли только значения {{Inline-code|elapsed|lang=rsplus}} и рассчитали медиану (Медиана является более устойчивой мерой центральной тенденции при асимметрии распределения, что, как правило, характерно для измерения времени).

Вместо подобных решений можно использовать специальные пакеты, предназначенные для измерения производительности кода, в частности, пакеты {{Inline-code|rbenchmark|lang=rsplus}} и {{Inline-code|microbenchmark|lang=rsplus}}. Основной принцип работы этих пакетов заключается в многократном выполнении выражений и расчёта ряда интегральных показателей, в частности, суммы, среднего значения или медианы времени выполнения всех попыток.

== Пакет rbenchmark ==

== Пакет microbenchmark ==