1
$\begingroup$

I want to print a timer that starts at 0 when an evaluation begins and stops when the evaluation is completed. I have come up with the following solution using Clock and Dynamic but it's a bit clumsy.

time = AbsoluteTiming[
   clock = Dynamic[Clock[1000]];
   Print["Evaluating... Time: ", Dynamic[clock]];
   Pause[2];
   ];
clock = time[[1]];

Furthermore, if I want to time several evaluations one after the other, I have to introduce new variables time1 time2, clock1 clock2 etc. so the previous output doesn't get overwritten, which is annoying.

Is there a better way to do this?

Alternatively, I would be happy to only print the evaluation time after the computation has finished. But then I can't get the time to print on the same line as "Evaluating..." becuase Print always creates a new line. The solution would be to use WriteString instead of Print, but I like the Style and Dynamic functionalities of Print, which WriteString does not support.

Reply to Domen's comment:

In the end I guess the purpose is largely aesthetic. I have looked into Monitor and PrintTemporary but have not found them useful for this task (of course I could be wrong about that). Say I'm computing a series expansion with Series that takes a long time to finish. Then I would like to print some text when the computation starts (for example, "Starting series expansion... "). Then, when the computation is finished, I would like to add the evaluation time to this print output such that it reads "Starting series expansion... Time: 10.234" if it took 10.234 seconds. A nice (purely aesthetic) bonus would be if the timer could be shown in real-time, starting at 0 seconds and stopping at 10.234.

As I said above, printing the evaluation time after the evaluation has finished can be done using WriteString, but I wonder if there is a solution using Print.

$\endgroup$
2
  • 1
    $\begingroup$ Welcome to StackExchange! What exactly is you overall purpose? If you want to have a good measurement of the evaluation time of some computation, then adding any kind of real-time monitoring in between the calculation will inevitably make the computation slightly longer. Also, do you know about Monitor and PrintTemporary? $\endgroup$
    – Domen
    Mar 22, 2023 at 13:32
  • $\begingroup$ Thanks for your comment. I have posted my reply as an edit to my original question because it was too long to post as a comment. $\endgroup$
    – oakley09
    Mar 22, 2023 at 16:00

1 Answer 1

1
$\begingroup$
SetAttributes[timeit, HoldFirst];
timeit[expr_, label_] := 
 Module[{result, time}, 
  PrintTemporary["Evaluating ", label, "... Time: ", 
   Dynamic[Refresh[Clock[Infinity], UpdateInterval -> 1/2]], 
   " s"]; {time, result} = AbsoluteTiming[expr]; 
  Print[label <> " completed in ", time, " s"];
  result
  ]

timeit[(Pause[3]; Series[Sin[x], {x, 0, 3}]), "Series expansion"]

timing

Alternatively, you can use EchoTiming.

SetAttributes[timeit2, HoldFirst];
timeit2[expr_, label_] := 
 EchoTiming[
  PrintTemporary["Evaluating ", label, "... Time: ", 
   Dynamic[Refresh[Clock[Infinity], UpdateInterval -> 1/2]]]; expr, 
  label <> " completed"]

timeit2[(Pause[3]; Series[Sin[x], {x, 0, 3}]), "Series expansion"]

timeit2

$\endgroup$
2
  • $\begingroup$ (+1) Wow ,Super. $\endgroup$ Mar 22, 2023 at 17:16
  • $\begingroup$ Very cool, thank you! I would upvote but don't have enough reputation yet. $\endgroup$
    – oakley09
    Mar 22, 2023 at 22:35

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.