Markus Grassl on Fri, 21 Oct 2022 16:41:19 +0200


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

Re: suggestion: timer format


Dear Ruud,

Thanks for the detailed explanation.

My question was to some extent triggered by laziness.

In my code, I just enable the built-in timing information using

  default(timer,1)

which will reported both the total CPU time and the wall clock (real time) spent on commands, e.g.,

  cpu time = 73h, 13min, 28,457 ms, real time = 2h, 12,222 ms.

It is again no big deal to write a script to parse this timing information, for which the number of minutes in the real time is zero and hence omitted in the printing. Yet another option would be to change the hard-coded printing format and compile an adjusted version of gp.

But I am thinking that others might also appreciate some flexibility  for the built-in functions instead of adding their own time measurements to their code.


Best

Markus



Am 21/10/2022 um 16:20 schrieb Ruud H.G. van Tol:

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.