Время выполнения функции измерения в 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 функции, если вы предпочитаете. Посмотрите этот другой ТАК вопрос

Функция секундомера в R

Вы можете использовать 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
Другие вопросы по тегам