Время выполнения функции измерения в R
Существует ли в R стандартизированный способ измерения времени выполнения функции?
Очевидно, я могу взять system.time
до и после выполнения, а затем возьмите разницу между ними, но я хотел бы знать, есть ли какой-то стандартизированный способ или функция (хотел бы не изобретать колесо).
Кажется, я помню, что когда-то использовал что-то вроде ниже:
somesysfunction("myfunction(with,arguments)")
> Start time : 2001-01-01 00:00:00 # output of somesysfunction
> "Result" "of" "myfunction" # output of myfunction
> End time : 2001-01-01 00:00:10 # output of somesysfunction
> Total Execution time : 10 seconds # output of somesysfunction
15 ответов
Другой возможный способ сделать это - использовать Sys.time():
start.time <- Sys.time()
...Relevent codes...
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
Не самый элегантный способ сделать это, по сравнению с приведенным выше ответом, но, безусловно, способ сделать это.
Встроенная функция system.time()
сделаю это.
Используйте как: system.time(result <- myfunction(with, arguments))
Как сказала Андри, system.time()
работает отлично. Для короткой функции я предпочитаю ставить replicate()
в этом:
system.time( replicate(10000, myfunction(with,arguments) ) )
microbenchmark
является легким (~50 КБ) пакетом и более или менее стандартным способом в R для сравнения нескольких выражений и функций:
microbenchmark(myfunction(with,arguments))
Например:
> microbenchmark::microbenchmark(log10(5), log(5)/log(10), times = 10000)
Unit: nanoseconds
expr min lq mean median uq max neval cld
log10(5) 0 0 25.5738 0 1 10265 10000 a
log(5)/log(10) 0 0 28.1838 0 1 10265 10000
Здесь оба выражения были оценены 10000 раз, со средним временем выполнения около 25-30 нс.
Существует также proc.time()
Вы можете использовать так же, как Sys.time
но это дает вам аналогичный результат system.time
,
ptm <- proc.time()
#your function here
proc.time() - ptm
Основное различие между использованием
system.time({ #your function here })
это то, что proc.time()
Метод по-прежнему выполняет вашу функцию вместо того, чтобы просто измерять время... и, кстати, мне нравится использовать system.time
с {}
внутри, чтобы вы могли положить множество вещей...
Немного более приятный способ измерения времени выполнения - использование пакета rbenchmark. Этот пакет (легко) позволяет вам указать, сколько раз будет повторяться ваш тест и должен ли быть относительный эталон.
Смотрите также связанный вопрос на stats.stackexchange
Пакет "Tictoc" дает вам очень простой способ измерения времени выполнения. Документация находится по адресу: https://cran.fhcrc.org/web/packages/tictoc/tictoc.pdf.
install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
toc()
Чтобы сохранить прошедшее время в переменной, вы можете сделать:
install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
exectime <- toc()
exectime <- exectime$toc - exectime$tic
Хотя другие решения полезны для одной функции, я рекомендую следующий фрагмент кода, который является более общим и эффективным:
Rprof ( tf <- "log.log", memory.profiling = TRUE )
your code must be in between
Rprof ( NULL ) ; print ( summaryRprof ( tf ) )
Еще один простой, но очень мощный способ сделать это с помощью пакета profvis
, Он не только измеряет время выполнения вашего кода, но и позволяет детализировать каждую выполняемую вами функцию. Это может быть использовано и для Shiny.
library(profvis)
profvis({
#your code here
})
Нажмите здесь для некоторых примеров.
Вы можете использовать MATLAB-стиль tic
-toc
функции, если вы предпочитаете. Посмотрите этот другой ТАК вопрос
Вы можете использовать
Sys.time()
. Однако, когда вы записываете разницу во времени в таблице или файле CSV, вы не можете просто сказать
end - start
. Вместо этого вы должны определить единицу:
f_name <- function (args*){
start <- Sys.time()
""" You codes here """
end <- Sys.time()
total_time <- as.numeric (end - start, units = "mins") # or secs ...
}
Тогда вы можете использовать
total_time
который имеет правильный формат.
Компилируя все ответы выше, я решил использовать эти упрощенные функции тик-так.
tic <- function(){ start.time <<- Sys.time() }
toc <- function(){ round(Sys.time() - start.time) }
для использования в качестве:
tic()
Sys.sleep(3)
toc()
и который печатает:
Разница во времени 3 секунды
bench::mark()
из пакетаbench
используется для тестирования одного или ряда выражений, мы считаем, что он имеет ряд преимуществ перед альтернативами. источник
Использовать:
bench::mark(log10(5))
#> # A tibble: 1 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 log10(5) 212ns 274ns 2334086. 0B 0
Создано 2021-08-18 пакетом REPEX (v2.0.1)
В нескольких ответах упоминается разница в два s, т.е.
start <- Sys.time()
## ... code here ... ##
end <- Sys.time()
end - start
Это печатает результат в удобочитаемом формате, например, «разница во времени 2 секунды». Однако, поскольку единицы измерения могут варьироваться (от «секунд» до «минут» и «дней»), менее полезно, скажем, сравнивать несколько сред выполнения на равных условиях с помощью этого метода, если их единицы различаются.
Для неинтерактивных целей предпочтительно указывать единицу времени.
В частности, возвращает объект. Взяв разницу двух s, вы получите объект класса
difftime
, у которого есть атрибут "единицы". В
`-`
операция, в частности, определена для использования
difftime()
при использовании с
POSIXct
. То есть,
time2 - time1
эквивалентно
difftime(time2, time1)
Чтобы указать атрибут единиц измерения, добавьте
units=
аргумент, напр.
difftime(time2, time1, units="secs")
Подводя итог , можно использовать
Sys.time()
измерять время выполнения с заданной единицей измерения (секунды, минуты и т. д.), т.е.
start <- Sys.time()
## ... code here ... ##
end <- Sys.time()
difftime(end, start, units="secs")
library(rbenchmark)
sleep_func <- function() { Sys.sleep(0.5) }
benchmark(sleep_func())
вне:
test replications elapsed relative user.self sys.self user.child sys.child
1 sleep_func() 100 50.08 1 0.02 0 NA NA