R - Set Execution Time Limit in Loop

R - Set execution time limit in loop

The function evalWithTimeout of package R.utils does this.

evalWithTimeout(Sys.sleep(10), timeout = 1)

(times are in seconds).

Note: I have not used this function a lot, I liked your question so I did some googling around and found this.

Limiting the time that a function processes in an R for loop

withTimeout() from package R.utils, in concert with tryCatch(), might provide a cleaner solution.

For example:

require(R.utils)

for(i in 1:5) {
tryCatch(
expr = {
withTimeout({Sys.sleep(i); cat(i, "\n")},
timeout = 3.1)
},
TimeoutException = function(ex) cat("Timeout. Skipping.\n")
)
}

# 1
# 2
# 3
# Timeout. Skipping.
# Timeout. Skipping.

In the artificial example above:

  • The first argument to withTimeout() contains the code to be evaluated within each loop.

  • The timeout argument to withTimeout() sets the time limit in seconds.

  • The TimeoutException argument to tryCatch() takes a function that is to be executed when an iteration of the loop is timed out.

How to re-run a piece of code if it hangs for more than x seconds?

One possible implementation:

run <- function(x,timeout) {
res <- tryCatch(R.utils::withTimeout(square_slowly(x),timeout=timeout),error=function(cond) NULL)
if (is.null(res)) res <- Recall(x,timeout)
return(res)
}

run(3,timeout = 5)
it took 4 seconds
[1] 9

Or in functional form:

run <- function(.f,...,timeout,trial=1) {
cat('run',trial,'\n')
res <- tryCatch(R.utils::withTimeout(do.call(.f,list(...)),timeout=timeout),error=function(cond) NULL)
if (is.null(res)) res <- Recall(.f=.f,unlist(list(...)),timeout=timeout,trial = trial + 1)
return(res)
}
run(square_slowly,3,timeout = 5)

run 1
run 2
run 3
run 4
run 5
run 6
it took 4 seconds
[1] 9

Skipping slow tasks in a loop in R

Using https://www.rdocumentation.org/packages/R.utils/versions/2.5.0/topics/withTimeout as a source. Here's a test unit that works as expected.

foo = function() {
print("Tic");
x <- ceiling(runif(1) * 100)+1;
for (kk in 1:x) {
print(kk);
Sys.sleep(runif(1));
}
print("Tac");
}

bar = function() {
for (i in 1:100) {
tryCatch({
res <- withTimeout({
foo();
}, timeout=1.08);
}, TimeoutException=function(ex) {
cat("Timeout. Skipping.\n");
});
print(i);
}
}

So the question is, is there an error that is thrown by interrupting by sim.rateshift.taxa that is not being caught, use error as thc mentions in order to catch that but use the TimeoutException to skip over proper timeouts

There is also a problem with setting too low a time limit:

https://github.com/mhahsler/arules/issues/22

You may want to simply use setTimeLimit yourself and ensure that transient is set to TRUE that way you have finer control.

Here's an example taken from http://blog.revolutionanalytics.com/2014/10/r-in-production-controlling-runtime.html

system.time(Sys.sleep(5))

##user system elapsed
## 0.000 0.000 5.005

system.time(local({
setTimeLimit(elapsed = 1, transient = TRUE)
Sys.sleep(5)
}))

## Error in Sys.sleep(5): reached elapsed time limit

## Timing stopped at: 0 0 5.006


Related Topics



Leave a reply



Submit