8
$\begingroup$

I need to write code like this: Do operation 1, but if it takes more that 5 seconds then stop it and do operation 2. Is it possible to do this somehow without manual interruption?

$\endgroup$
  • 4
    $\begingroup$ You can try TimeConstrained. Example from help TimeConstrained[Do[i^2, {i, 1000000}], 1] will terminate computation if it takes more than one second. You can adjust the time as needed. $\endgroup$ – Nasser Jun 13 '14 at 19:32
  • $\begingroup$ Thank you, TimeConstrained is what I actually need $\endgroup$ – user15933 Jun 13 '14 at 21:40
  • $\begingroup$ Using Names is often useful. The first entry for Names["Time*"] would have answered your question. $\endgroup$ – Bob Hanlon Mar 28 at 17:51
15
$\begingroup$

You can use TimeConstrained for this. Here is an example

tMax = 1;  (*second*)
f1[n_Integer] := Do[i^2, {i, n}];
TimeConstrained[f1[10^7], tMax]
(* $Aborted *)

You can use CheckAbort to check which function timed out or not, since TimeConstrained generated $Aborted. Here is an example

tMax = 5;  (*second*)
f1[n_Integer] := Do[i^2, {i, n}];
n = {10^1, 10^6, 10^8};
CheckAbort[TimeConstrained[f1[#], 5], "timed out!"] & /@ n
(*  {Null, Null, $Aborted}  *) 

So the last one timed out, but not the first two. You can customize this more as needed. (I need to find why the message "timed out" did not show up, but will look at this soon)

$\endgroup$
  • $\begingroup$ It looks like CheckAbort doesnt see the interrupt caused by TimeConstrained (if you do Alt-. quick enough you get the CheckAbort expression .. ) $\endgroup$ – george2079 Jun 13 '14 at 20:16
  • $\begingroup$ @george2079 yes, something is strange with CheckAbort here. it should have returned the message. I posted a question on chat now about it. Not relevant to this answer, as one does not have to use it. But it is strange. $\endgroup$ – Nasser Jun 13 '14 at 20:19
  • $\begingroup$ @Nasser - just found a horrible solution: CheckAbort[TimeConstrained[f1[#], 5], ""] & /@ n /. $Aborted -> "timed out!" $\endgroup$ – eldo Jun 13 '14 at 21:15
  • 2
    $\begingroup$ @Nasser: CheckAbort[TimeConstrained[f1[#], 5, Abort[]], "timed out!"] & /@ n $\endgroup$ – ciao Jun 14 '14 at 0:37
1
$\begingroup$

I would use the 3-arg version of TimeConstrained:

op1[time_] := (Pause[time]; Print[1]; 1)
op2 := (Print[2]; 2)

An example where op1 doesn't time out:

TimeConstrained[op1[2], 3, op2]

1

1

Notice that op2 never evaluates. Next, an example where op1 times out:

TimeConstrained[op1[2], 1, op2]

2

2

This time op1 was aborted, and so it didn't get a chance to print 1, while op2 does evaluate and prints 2.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.