9
$\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$
3
  • 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
    Commented Jun 13, 2014 at 19:32
  • $\begingroup$ Thank you, TimeConstrained is what I actually need $\endgroup$
    – user15933
    Commented Jun 13, 2014 at 21:40
  • $\begingroup$ Using Names is often useful. The first entry for Names["Time*"] would have answered your question. $\endgroup$
    – Bob Hanlon
    Commented Mar 28, 2019 at 17:51

2 Answers 2

16
$\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, Abort[]], "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$
5
  • $\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
    Commented Jun 13, 2014 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
    Commented Jun 13, 2014 at 20:19
  • $\begingroup$ @Nasser - just found a horrible solution: CheckAbort[TimeConstrained[f1[#], 5], ""] & /@ n /. $Aborted -> "timed out!" $\endgroup$
    – eldo
    Commented Jun 13, 2014 at 21:15
  • 3
    $\begingroup$ @Nasser: CheckAbort[TimeConstrained[f1[#], 5, Abort[]], "timed out!"] & /@ n $\endgroup$
    – ciao
    Commented Jun 14, 2014 at 0:37
  • $\begingroup$ @ciao This works! $\endgroup$ Commented Jan 24, 2023 at 15:06
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 and acknowledge you have read our privacy policy.

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