Computation with time limit

2020-02-28 07:22发布

I'm trying to write a construct which allows me to run computations in a given time window. Something like:

def expensiveComputation(): Double = //... some intensive math

val result: Option[Double] = timeLimited( 45 ) { expensiveComputation() }

Here the timeLimited will run expensiveComputation with a timeout of 45 minutes. If it reaches the timeout it returns None, else it wrapped the result into Some.

I am looking for a solution which:

  • Is pretty cheap in performance and memory;
  • Will run the time-limited task in the current thread.

Any suggestion ?

EDIT

I understand my original problem has no solution. Say I can create a thread for the calculation (but I prefer not using a threadpool/executor/dispatcher). What's the fastest, safest and cleanest way to do it ?

9条回答
Fickle 薄情
2楼-- · 2020-02-28 08:15

In the currentThread?? Phhhew... Check after each step in computation Well if your "expensive computation" can be broken up into multiple steps or has iterative logic you could capture the time when you start and then check periodically between your steps. This is by no means a generic solution but will work.

For a more generic solution you might make use of aspects or annotation processing, that automatically litters your code with these checks. If the "check" tells you that your time is up return None.

Ill ponder a solution in java quickly below using annotations and an annotation processor...

public abstract Answer{}
public class Some extends Answer {public Answer(double answer){answer=answer}Double answer = null;}
public class None extends Answer {}


//This is the method before annotation processing
@TimeLimit(45)
public Answer CalculateQuestionToAnswerOf42() {
 double fairydust = Math.Pi * 1.618;
 double moonshadowdrops = (222.21) ^5;
 double thedevil == 222*3;
 return new Answer(fairydust + moonshadowdrops + thedevil);
}

//After annotation processing
public Answer calculateQuestionToAnswerOf42() {
 Date start = new Date() // added via annotation processing;
 double fairydust = Math.Pi * 1.618; 
 if(checkTimeout(start, 45)) return None; // added via annotation processing;
 double moonshadowdrops = (222.21) ^5;
 if(checkTimeout(start, 45)) return None; // added via annotation processing;
 double thedevil == 222*3;
 if(checkTimeout(start, 45)) return None; // added via annotation processing;
 return new Answer(fairydust + moonshadowdrops + thedevil);
}
查看更多
啃猪蹄的小仙女
3楼-- · 2020-02-28 08:19

If you are ok for the code of expensiveComputation to check Thread.interrupted() frequently, pretty easy. But I suppose you are not.

I don't think there is any solution that will work for arbitrary expensiveComputation code. The question is what are you prepared to have as constraint on expensiveComputation.

You have the deprecated and quite unsafe Thead.stop(Throwable) too. If your code does not modify any object but those it created by itself, it might work.

查看更多
手持菜刀,她持情操
4楼-- · 2020-02-28 08:22

To the best of my knowledge, either you yield (the computation calls to some scheduler) or you use a thread, which gets manipulated from the "outside".

查看更多
登录 后发表回答