# Converting Timing to TimeObject

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.

• Doesn't TimeObject refer to an instant in time? It doesn't seem to make sense to convert a duration to a TimeObject. Mar 13, 2020 at 18:02
• @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. Mar 13, 2020 at 18:09
• Try SetAttributes[unitTiming, HoldAll] Mar 13, 2020 at 18:10
• @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? Mar 13, 2020 at 18:16
• @Szabolcs, this is really a separate question but is it possible to obtain both Timing and AbsoluteTiming for the same input? Mar 13, 2020 at 18:17

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: 