10 ответов
В R много инструментов для профилирования, как упоминал Дирк. Если вам нужна простота tic/toc, то вы можете сделать это и в R.
РЕДАКТИРОВАТЬ: я каннибализировал функциональность сбора мусора из пакета MATLAB, и tic
Теперь вы можете выбрать, хотите ли вы узнать общее прошедшее время или только время пользователя.
tic <- function(gcFirst = TRUE, type=c("elapsed", "user.self", "sys.self"))
{
type <- match.arg(type)
assign(".type", type, envir=baseenv())
if(gcFirst) gc(FALSE)
tic <- proc.time()[type]
assign(".tic", tic, envir=baseenv())
invisible(tic)
}
toc <- function()
{
type <- get(".type", envir=baseenv())
toc <- proc.time()[type]
tic <- get(".tic", envir=baseenv())
print(toc - tic)
invisible(toc)
}
Использование, например, tic(); invisible(qr(matrix(runif(1e6), nrow=1e3))); toc()
На CRAN есть пакет эмуляции MATLAB matlab. Он имеет реализации tic
а также toc
(но они выглядят очень похоже на функции в ответе Ричи Коттона; "истекший" используется вместо "user.self" в proc.time()
)
> tic
function (gcFirst = FALSE)
{
if (gcFirst == TRUE) {
gc(verbose = FALSE)
}
assign("savedTime", proc.time()[3], envir = .MatlabNamespaceEnv)
invisible()
}
<environment: namespace:matlab>
> toc
function (echo = TRUE)
{
prevTime <- get("savedTime", envir = .MatlabNamespaceEnv)
diffTimeSecs <- proc.time()[3] - prevTime
if (echo) {
cat(sprintf("elapsed time is %f seconds", diffTimeSecs),
"\n")
return(invisible())
}
else {
return(diffTimeSecs)
}
}
<environment: namespace:matlab>
Очень простая эквивалентность с tic и toc, которую вы могли бы иметь:
tic=proc.time()[3]
...code...
toc=proc.time()[3] - tic
Где [3], потому что мы заинтересованы в третьем элементе в векторе, возвращаемом proc.time(), который истек время.
Прямых эквивалентов tic и toc не существует.
Посмотри пожалуйста help(system.time)
а также руководство по расширению R для профилирования. Обсуждение инструментов профилирования и профилирования также содержится на слайдах "Введение в HPC с R", на которые ссылается обзор задач " Высокопроизводительные вычисления с R".
Закрытие Подход
Очень простой и простой способ сделать это - использовать замыкание (что означает наличие функции внутри функции):
tic <- function () {
now <- proc.time()
function () {
proc.time() - now
}
}
Вы запускаете таймер так:
toc <- tic()
И тогда вы получите время обратно так:
toc()
Который выводит именованный вектор, который печатается так:
user system elapsed
0.008 0.004 2.055
Даже с простотой этой версии вы также получаете все функциональные возможности версий Matlab и Richie Cotton, а также дополнительную возможность запуска нескольких таймеров:
toc1 <- tic()
toc2 <- tic()
Существует относительно новый пакет tictoc, который воспроизводит функции точно так же, как вы бы использовали их в Matlab.
http://cran.r-project.org/web/packages/tictoc/index.html
## Basic use case
tic()
print("Do something...")
Sys.sleep(1)
toc()
# 1.034 sec elapsed
На дату 2015-03-25, а возможно и раньше, пакет pracma содержит функции tic()
а также toc()
,
Пример:
> library(pracma)
> tic()
> for(i in 1:10000) mad(runif(10000)) # kill time
> toc()
elapsed time is 18.610000 seconds
Нет, но здесь решение в одну строку.
time.it<-function(f) { a<-proc.time(); out<-f(); print(proc.time()-a); out }
И пример для использования:
result<-time.it(function(){ A<-matrix(runif(5000^2),nrow=5000); b<-runif(5000); solve(A,b) } )
user system elapsed
12.788 12.268 8.623
В остальном, микробенчмарк мой любимый с точки зрения пакетов.
Просто для полноты: вы можете "имитировать" тик и ток в R, так что вы можете написать
tic
## do something
toc
без скобок. Хитрость заключается в том, чтобы злоупотреблять print
функция, как показано в Fun: tic и toc в R:
tic <- 1
class(tic) <- "tic"
toc <- 1
class(toc) <- "toc"
print.tic <- function(x, ...) {
if (!exists("proc.time"))
stop("cannot measure time")
gc(FALSE)
assign(".temp.tictime", proc.time(), envir = .GlobalEnv)
}
print.toc <- function(x,...) {
if (!exists(".temp.tictime", envir = .GlobalEnv))
stop("did you tic?")
time <- get(".temp.tictime", envir = .GlobalEnv)
rm(".temp.tictime", envir = .GlobalEnv)
print(res <- structure(proc.time() - time,
class = "proc_time"), ...)
invisible(res)
}
Так что печатать
tic
Sys.sleep(2)
toc
должно привести к чему-то вроде этого:
user system elapsed
0.000 0.000 2.002
Как я уже сказал, это трюк; system.time
, Rprof
и пакеты, такие как rbenchmark
способ измерения вычислительного времени в R.
install.packages("tictoc")
library(tictoc)
# Timing nested code.
# The string provided in the call to tic() becomes a prefix to the output of toc()
tic("outer")
Sys.sleep(1)
tic("middle")
Sys.sleep(2)
tic("inner")
Sys.sleep(3)
toc() # inner
# inner: 3.004 sec elapsed
toc() # middle
# middle: 5.008 sec elapsed
toc() # outer
# outer: 6.016 sec elapsed
Пакет tictoc реализует функциональность, описанную в предыдущих ответах - спасибо за вдохновение! Пакет также добавляет вложенное время, собирая время в пользовательских переменных, пользовательских сообщениях и обратных вызовах.