如何在R中停止一个耗时太长的功能并给它一个替代方案?

时间:2022-08-05 22:34:27

I'm trying to do a thing "the right way". Sometimes "the right way" takes too long, depending on the inputs. I can't really know a priori when this will be. When "the right way" is taking too long, I want to go to "the hackish way". How do I make R monitor how long a particular task as taken, and give it something else to do if a threshold has passed? I'd imagine that this will be part of the try family, but I'm not quite sure what to call it or google for.

我正试图以“正确的方式”做事。有时“正确的方式”需要太长时间,具体取决于输入。我真的不知道这是什么时候的先验。当“正确的方式”花费太长时间时,我想转向“黑客的方式”。如何使R监视特定任务的持续时间,并在阈值过去时给它做其他事情?我想这将是试用系列的一部分,但我不太确定该怎么称呼它或google for。

Dummy example below. When slow.func takes too long, I want interuptor to stop it and call fast.func instead.

下面的虚拟例子。当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)

2 个解决方案

#1


9  

The R package R.utils has a function evalWithTimeout that's pretty much exactly what you're describing. If you don't want to install a package, evalWithTimeout relies on the less user friendly R base function setTimeLimit

R包R.utils有一个函数evalWithTimeout,它几乎就是你所描述的。如果您不想安装软件包,evalWithTimeout依赖于用户友好的R基函数setTimeLimit

Your code would look something like this:

您的代码看起来像这样:

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)

#2


1  

The answer of "nwknoblauch" does not work for me unless I change "warning" by "silent" inside the interruptor function.

“nwknoblauch”的答案对我不起作用,除非我在中断函数内部通过“静音”改变“警告”。

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="silent")
  if(is.null(results)){
    results <- ALTFUN(args)
  }
  return(results)
}   
interruptor(FUN = slow.func,args=2,time.limit=3,ALTFUN = fast.func)

#1


9  

The R package R.utils has a function evalWithTimeout that's pretty much exactly what you're describing. If you don't want to install a package, evalWithTimeout relies on the less user friendly R base function setTimeLimit

R包R.utils有一个函数evalWithTimeout,它几乎就是你所描述的。如果您不想安装软件包,evalWithTimeout依赖于用户友好的R基函数setTimeLimit

Your code would look something like this:

您的代码看起来像这样:

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)

#2


1  

The answer of "nwknoblauch" does not work for me unless I change "warning" by "silent" inside the interruptor function.

“nwknoblauch”的答案对我不起作用,除非我在中断函数内部通过“静音”改变“警告”。

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="silent")
  if(is.null(results)){
    results <- ALTFUN(args)
  }
  return(results)
}   
interruptor(FUN = slow.func,args=2,time.limit=3,ALTFUN = fast.func)