2

I am using GNU time for benchmarking and would like to measure real, user and sys time to the nearest millisecond. That is, I want to measure seconds to 3 decimal places, not the default 2. Does GNU time offer such an option?

5
  • Are you using the built-in/keyword time or the external time? Commented Aug 16, 2019 at 15:50
  • I'm using the build-in time, I believe. It is /usr/bin/time. Commented Aug 16, 2019 at 15:53
  • Sorry, I believe I am using GNU time. I am executing the command from a Node.js Child Process, which itself is running inside a Docker container. The default behaviour is to print: %Uuser %Ssystem %Eelapsed %PCPU (%Xtext+%Ddata %Mmax)k %Iinputs+%Ooutputs (%Fmajor+%Rminor)pagefaults %Wswaps Commented Aug 16, 2019 at 15:58
  • Related: unix.stackexchange.com/questions/70653/… Commented Aug 16, 2019 at 17:13
  • Good find. Read that earlier but I wasn't able to get much from it. Commented Aug 16, 2019 at 18:11

2 Answers 2

2

It doesn't look like you could, the man page does list a number of formatting options, but there's no provision for setting the accuracy. For example, %e, %S and %U seem to always give the output with two decimal places.

On the other hand, Bash's builtin time does support setting the number of digits after the decimal point, up to 3, so you might be able to use it to get what you wanted. The TIMEFORMAT environment variable controls the output format:

$ TIMEFORMAT='real: %3R user: %3U sys: %3S cpu: %P' bash -c 'time sleep 1.233' real: 1.234 user: 0.000 sys: 0.000 cpu: 0.00 

Or just without setting TIMEFORMAT, since the default output also shows three digits. It does separate minutes though:

$ bash -c 'time sleep 1.233' real 0m1.234s user 0m0.000s sys 0m0.000s 

The getrusage() system call gives the times as struct timeval, so up to microseconds, so I suppose you could make your own implementation of time to get more accuracy. A whole another thing is how accurate the numbers actually are.

2
  • Thanks! I was calling time from a Node.js child_process instance which enforced use of GNU time for some reason or another. I was finally able to enforce bash time using /bin/bash -c "time <my command>". Shame about GNU time not allowing formatting, though. Commented Aug 16, 2019 at 18:10
  • @JacobBaird, oh, right, the default format already shows three digits, so it's not even necessary to modify it. Setting TIMEFORMAT to %3R %3U %3S might make the output easier to parse, since there would be less to parse and you'd get raw seconds instead of seconds + minutes. Commented Aug 16, 2019 at 19:12
1

With GNU time, not only the resolution is limited to centisecond, but for %E, it also uses a M:SS.SS format, switching to H:MM:SS.SS if greater than one hour which is harder to parse.

It's hardcoded, nothing can be done about it.

However, several shells have resource usage reporting facility builtin (some like ksh93 or bash limited to CPU and real time only) and several can let you specify the format in a more fine-grained way.

Starting with csh (the BSD shell) from the 80s (resource usage gathering and reporting was initially from BSD).

In tcsh, the second word in the $time array can be used to specify the format:

set time = (. 'elapsed=%E user=%U system=%S') 

For %U/%S, that's with millisecond precision, for %E, it's the same M:SS.SS / H:MM:SS.SS as with GNU time.

In zsh, that's with the TIMEFMT variable (added in 2.0 from 1991) where, in current versions:

  • %E gives you the elapsed time in S.SSs format.
  • %*E gives S.SSS, switching to M:SS.SS and H:MM:SS.SS as needed
  • %mE gives it in number of milliseconds followed by ms
  • %uE gives it in number of microseconds followed by us

Same for %U/%S for user/sys CPU time.

bash added its own variable in 2.0 in 1996 but decided to call it TIMEFORMAT instead, it's limited to elapsed/user/sys, and for some reason decided to use %R instead of %E for the elapsed time (even though %R in most other implementations is for the number of minor page faults; it does supports %E as an undocumented alias).

You can specify a precision of up to milliseconds (the default): %3R and %3lR to switch to MmSS.SSSS for instance.

ksh93 seems to have copied bash in ksh93o from 2003 except it doesn't support %E as an alias for %R.

bosh has $TIMEFORMAT but uses the more common time directives like from BSD/csh/GNU time/zsh (%E for elapsed time, not %R) though with the same %3E and %3lE as in bash. Precision can go to microseconds though.

So, comparing different tools for the elapsed/user/sys times with maximum precision:

$ /usr/bin/time -f %E/%U/%S sleep 1 0:01.00/0.00/0.00 $ tcsh -c 'set time = (. %E/%U/%S); time sleep 1' 0:01.00/0.000/0.000 $ bash -c 'TIMEFORMAT=%E/%U/%S; time sleep 1' 1.002/0.000/0.002 $ ksh -c 'TIMEFORMAT=%R/%U/%S; time sleep 1' 1.000/0.000/0.000 $ zsh -c 'TIMEFMT=%uE/%uU/%uS; time sleep 1' 1002810us/0us/2408us $ bosh -c 'TIMEFORMAT=%6E/%6U/%6S; time sleep 1' 1.002229/0.000078/0.001997 

As maybe evidenced by those results above, that level of precision may not make a lot of sense. If your command runs for such a short time that you need millisecond precision, then you're not going to benchmark it much with time as a lot of that time is going to be down to the forking of a process, loading the executable, the shared library and doing the dynamic linking.

Timing a few hundred runs of it is likely to give you something more reliable. For instance, in zsh:

$ time uname > /dev/null uname > /dev/null 0.00s user 0.00s system 85% cpu 0.003 total 

Not useful.

$ (TIMEFMT='%uE/%uU/%uS'; repeat 5 time uname > /dev/null) 1729us/0us/1336us 1323us/1081us/0us 1264us/1083us/0us 1676us/0us/1400us 1814us/1627us/0us 

Hardly more useful.

$ time (repeat 1000 uname) > /dev/null ( repeat 1000; do; uname; done; ) > /dev/null 0.91s user 0.60s system 103% cpu 1.450 total 

Where you can replace s with ms above is likely be a more accurate representation of the time and effort it takes to run uname in a separate process.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.