1
$\begingroup$

What's the proper way to get Timing and post-process it for example to convert to a TimeObject as a defined function?

In line, this replacement works as intended:

Inverse[Table[RandomReal[], {3000}, {3000}]]; // Timing // 
 Replace[{timeSec_, value_} :> {TimeObject[{0, 0, timeSec}], value}]

gives (full form):

List[TimeObject[List[0,0,3.450302`],"Instant",None],Null]

but when trying to define a function to perform both the timing and conversion, the actual timing extracted is not that of the intended input expression:

unitTiming[expr_] := Timing[expr] // Replace[{timeSec_,value_}:> {TimeObject[{0,0,timeSec}],value}]

Testing on the matrix inversion above:

Inverse[Table[RandomReal[], {3000}, {3000}]]; // unitTiming

gives:

List[TimeObject[List[0,0,0.000011`],"Instant",None],Null]

I've tried several variations on the definition (eg using RightComposition) but can't get the desired results.

$\endgroup$
7
  • $\begingroup$ Doesn't TimeObject refer to an instant in time? It doesn't seem to make sense to convert a duration to a TimeObject. $\endgroup$
    – Szabolcs
    Mar 13 '20 at 18:02
  • $\begingroup$ @Szabolcs, that's a good point, b/c it zeros after 24hours, but for the my purposes it's more convenient than using say` UnitConvert[Quantity[timeSec,"Seconds"],"Minutes"]` because TimeObject auto-converts to minutes if > 60sec (ditto hours), whereas I'd have to manually tune the logic. In any case, using Quantity has the same problem. $\endgroup$ Mar 13 '20 at 18:09
  • 2
    $\begingroup$ Try SetAttributes[unitTiming, HoldAll] $\endgroup$
    – Szabolcs
    Mar 13 '20 at 18:10
  • $\begingroup$ @Szabolcs, that works, thanks. Can you explain why holding works in this case? One would expect Timing[expr] to already be evaluated on the input, prior to the Replace? $\endgroup$ Mar 13 '20 at 18:16
  • $\begingroup$ @Szabolcs, this is really a separate question but is it possible to obtain both Timing and AbsoluteTiming for the same input? $\endgroup$ Mar 13 '20 at 18:17
1
$\begingroup$

This answer addresses Szabolcs' points in comments, including avoiding TimeObject

(* returns S, MS, HMS depending on the magnitude of the input *)
minimalTimeQuantity[time_] := Replace[time, {
    t_ /; (t < 60) :> Quantity[MixedMagnitude[{t}], MixedUnit[{"Seconds"}]],
    t_ /; (t < 3600) :> 
     Quantity[MixedMagnitude[{0, t}], MixedUnit[{"Minutes", "Seconds"}]],
    t_ :> Quantity[MixedMagnitude[{0, 0, t}], 
      MixedUnit[{"Hours", "Minutes", "Seconds"}]]}
   ];

Then package output for both types of timing:

(* data structure to return both timing and absolute timing *)
timingsAssociation[t_, absT_] := <|"Timing" -> minimalTimeQuantity[t], 
  "Absolute Timing" -> minimalTimeQuantity[absT]|>

Finally, the actual timing function returning quantities:

timings[expr_] := 
 AbsoluteTiming[Timing[expr]] // 
  Replace[{{absT_, {t_, Null}} :> 
     timingsAssociation[t, 
      absT], {absT_, {t_, value_}} :> {timingsAssociation[t, absT], value}}]
SetAttributes[timings, HoldAll]

Test:

Inverse[Table[RandomReal[], {1000}, {1000}]]; // timings

gives:

enter image description here

$\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.