Jim
Jim

Reputation: 4767

Define a callback for command start

I am trying to automatically time execution of all top-level expressions. Task Handlers are almost what is needed, however they are called only after the command completes, rather than before.

An alternative approach would be to modify every top-level expression to be wrapped in system.time, however I am not aware of a method to do this either.

Upvotes: 3

Views: 332

Answers (3)

Jim
Jim

Reputation: 4767

For completeness here is a function you can use as a task callback to automatically cause a system notification for any top level command that takes more than 5 seconds to run.

# devtools::install_github("gaborcsardi/notifier")
notify_long_running <- function(second_cutoff = 5) {
  last <- proc.time()[1]
  function(expr, value, ok, visible) {
    duration <- proc.time()[1] - last
    if (duration > second_cutoff) {
      notifier::notify(msg = paste0(collapse = " ", deparse(expr)),
                       title = sprintf("Completed in %.02f (s)", duration))
    }
    last <<- proc.time()[1]
    TRUE
  }
}

addTaskCallback(notify_long_running())

Upvotes: 8

thc
thc

Reputation: 9705

Two years late, but try this solution to automatically time all commands:

proc <- function(...) {
    utime <- proc.time()[1]
    utime_diff <- utime-get0(".prev_time", envir=globalenv(), ifnotfound=0)
    options(prompt=paste0(utime_diff,"s> "))
    assign(".prev_time", utime, envir=globalenv())
    return(TRUE)
    }
ret <- addTaskCallback(proc)

The "user time" returned by proc.time doesn't increment when idle, so it'll only calculate the time spent running the command.

This gives you pretty close to accurate measure, down to a 10th of a second at least:

start_time <- proc.time()[1]

st_time <- system.time({for(x in 1:10000000) {
    log(x)
}})[1]

pt_time <- proc.time()[1] - start_time

print(paste("time using proc.time()", pt_time))
print(paste("time using syste.time()", st_time))

"time using proc.time() 1.908"

"time using syste.time() 1.884"

Upvotes: 2

Oliver Keyes
Oliver Keyes

Reputation: 3294

There's no real way to profile "top-level commands" because R doesn't know what those are. How are you defining them?

If system.time is not granular enough for you (because it doesn't look at individual pieces of code), my suggestion would be to go in the opposite direction and use Rprof, which allows you to start and stop the timing of expressions and, on output (summaryRprof()) prints a breakdown by function call. Mind you, this is by function call, not by "top-level function" call: if you're looking specifically for R to benchmark whatever you think of as a top-level function, system.time may indeed be your best bet

Upvotes: -2

Related Questions