gen*_*ser 18 error-handling time r
我正试图以"正确的方式"做事.有时"正确的方式"需要太长时间,具体取决于输入.我真的不知道这将是什么时候.当"正确的方式"花费太长时间时,我想要采取"黑客的方式".如何让R监视特定任务的持续时间,如果阈值已经过去,还要给它做其他事情?我想这将是try家庭的一部分,但我不太确定该怎么称呼它或谷歌.
下面的虚拟例子.如果slow.func花费的时间太长,我想interuptor停下来然后打个电话fast.func.
slow.func <- function(x){
Sys.sleep(x)
print('good morning')
}
fast.func <- function(x){
Sys.sleep(x/10)
print('hit snooze')
}
interuptor = function(FUN,args, time.limit, ALTFUN){
# START MONITORING TIME HERE
do.call(FUN,args)
# IF FUN TAKES TOO LONG, STOP IT, CALL A
do.call(ALTFUN,args)
}
interuptor(slow.func, list(x = 2), time.limit = 1, fast.func)
Run Code Online (Sandbox Code Playgroud)
小智 11
R包R.utils的功能evalWithTimeout几乎与您所描述的完全相同.如果您不想安装软件包,则evalWithTimeout依赖于用户友好的R基本功能setTimeLimit
您的代码看起来像这样:
library(R.utils)
slow.func <- function(x){
Sys.sleep(10)
return(x^2)
}
fast.func <- function(x){
Sys.sleep(2)
return(x*x)
}
interruptor = function(FUN,args, time.limit, ALTFUN){
results <- NULL
results <- evalWithTimeout({FUN(args)},timeout=time.limit,onTimeout="warning")
if(results==NULL){
results <- ALTFUN(args)
}
return(results)
}
interruptor(slow.func,args=2,time.limit=3,fast.func)
Run Code Online (Sandbox Code Playgroud)
对于任何想要不依赖于R.utils包的更轻量级解决方案的人,我最终使用了基于withTimeout()代码的最小解决方案。
foo <- function() {
time_limit <- 10
setTimeLimit(cpu = time_limit, elapsed = time_limit, transient = TRUE)
on.exit({
setTimeLimit(cpu = Inf, elapsed = Inf, transient = FALSE)
})
tryCatch({
# do some stuff
}, error = function(e) {
if (grepl("reached elapsed time limit|reached CPU time limit", e$message)) {
# we reached timeout, apply some alternative method or do something else
} else {
# error not related to timeout
stop(e)
}
})
}
Run Code Online (Sandbox Code Playgroud)