Ruud H.G. van Tol on Fri, 21 Oct 2022 16:21:12 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: suggestion: timer format



In this context, a time value is a duration (AKA delta),
with optionally a predefined start (AKA epoch), generally as a numerical number-of-seconds value, optionally fractional.

Example epochs:
a. the UNIX-epoch (1970-01-01 00:00:00 UTC);
b. the start time of the main code;
c. the start time of some other interesting part of the code;
d. a system dependent clock tick state (not in seconds);
e. a wallclock state;

Case a. can be used for rendering human-friendly calendar-date-time-strings. An outrageous example:

$ perl -Mstrict -mPOSIX -wE'
  say POSIX::strftime("%F %T", time(),0,0,1,0,70);
'
2022-10-20 12:37:16

I call this "outrageous" because it assumes that "int tm_sec, inside struct tm" can hold other values than 0-60 (yes, 60, consider leap seconds), and that the return value of time() fits in an int.

- - - -

In gp, one can use:
? default(prompt,":%s: ")
to change the prompt to (for example) show UNIX-epoch-deltas,
but a fractional-seconds-format isn't supported.
Also it doesn't change the builtin timer output format.

Cases b.-e. are often used in timing (AKA benchmarking),
so generally need values with a sub-second resolution.
For those I prefer to use explicit getabstime()-deltas.

? {
my (tc= getabstime(), tw= getwalltime());

alarm(2,while(1,1));  /* busy-loop */

my (dtc= getabstime()-tc, dtw= getwalltime()-tw);
printf( "dtc=%.3fs\n", dtc/1000 );
printf( "dtw=%.3fs\n", dtw/1000 )
}
dtc=1.997s
dtw=2.001s
cpu time = 1,998 ms, real time = 2,001 ms.


To format more, consider adding a function strtimef:

{
strtimef
( V= getabstime()
, S= strsplit("%0.0s|%02d|:%02d|:%02d|.%03d", "|")
, F= (~s, ~v)->if(v[1], s[1]= "%dd ")
)=
my
( t= V \ 1000
, v=
  [ t \ 86400
  , t \ 3600 % 24
  , t \ 60%60
  , t % 60
  , V % 1000
  ]
);
F( ~S, ~v );
call( strprintf, [ strjoin(S), v ] );
}


And test:

? apply(strtimef,[ 0, 1, 86400e3-1, 86400e3+1, getabstime(), getwalltime() ])
%3 =
[ "00:00:00.000"
, "00:00:00.001"
, "23:59:59.999"
, "1d 00:00:00.001"
, "00:01:06.705"
, "19286d 09:08:27.399"
]


-- Ruud

P.S. Just for inspiration:

? install( strftime_expand, "vssL" );

? now( fmt= "%F %T" )= {
my(buf= strjoin( Vec([], 200) ), buflen= #buf);
strftime_expand(fmt, buf, buflen);
buf }

? now()
%7 = "2022-10-21 15:52:35"
? now("%s")
%8 = "1666360361"
? now("%T")
%9 = "15:52:51"

(see `man strftime` for format details)


And for UTC:

? nowz()= {
call( strprintf,["%02d:%02d:%02d", Vecrev( Vecrev( digits( (getwalltime() \ 1000) % 86400, 60)), 3) ] )
}


On 2022-10-20 10:09, Markus Grassl wrote:
I understand that the printing of timing information is hard-coded in the function 'convert_time' in the file 'gplib.c'.

In order to simplify the parsing of timing information, I suggest to make the format more flexible. The user might want to switch the format using 'default'; e.g. printing in seconds only, or include zeros in the printing of minutes when the time exceeds one hour.