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?
2 Answers
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)
-
$\begingroup$ It looks like
CheckAbort
doesnt see the interrupt caused byTimeConstrained
(if you do Alt-. quick enough you get theCheckAbort
expression .. ) $\endgroup$ 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$– NasserCommented Jun 13, 2014 at 20:19 -
$\begingroup$ @Nasser - just found a horrible solution:
CheckAbort[TimeConstrained[f1[#], 5], ""] & /@ n /. $Aborted -> "timed out!"
$\endgroup$– eldoCommented Jun 13, 2014 at 21:15 -
3$\begingroup$ @Nasser:
CheckAbort[TimeConstrained[f1[#], 5, Abort[]], "timed out!"] & /@ n
$\endgroup$– ciaoCommented Jun 14, 2014 at 0:37 -
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.
TimeConstrained
. Example from helpTimeConstrained[Do[i^2, {i, 1000000}], 1]
will terminate computation if it takes more than one second. You can adjust the time as needed. $\endgroup$Names
is often useful. The first entry forNames["Time*"]
would have answered your question. $\endgroup$