Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Jul 2022 15:08:12 +0100
From:      Frank Leonhardt <freebsd-doc@fjl.co.uk>
To:        questions@freebsd.org
Subject:   Re: How do get elapsed time in milliseconds in a shell script?
Message-ID:  <b764d6fb-0e14-ad7f-4d70-25d066591d4c@fjl.co.uk>
In-Reply-To: <CAFMGiz8NcH1BMiRkftz67qd=6jicvPzrfagr40hSN94i87jxVw@mail.gmail.com>
References:  <4c98bb6d-a128-d10b-a896-6af11c06d41c@fjl.co.uk> <CAFMGiz8NcH1BMiRkftz67qd=6jicvPzrfagr40hSN94i87jxVw@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------V1NuJ2U88b7LRjHHXKm1eDbJ
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

On 18/07/2022 14:45, Tom Browder wrote:
>
>
> On Tue, Jul 12, 2022 at 03:09 Frank Leonhardt <freebsd-doc@fjl.co.uk> 
> wrote:
>
>     I thought this would be easy, but it's not!
>
>     I can get the time since the epoch to the nearest second (date
>     +%s), but
>     nothing more accurate. This was probably good enough in the 1970s
>     but I
>     think it's reasonable to want a better resolution even in a shell
>     script.
>
>
> I’m a wannabe FreeBSD user lurking here. Can you tell us more about 
> your use case?
>
> (Spoiler alert:  I’m a long time Unix/Linux user who now relies mostly 
> on Raku for other than very simple bash scripts.)
>
There is no use case here, other than trying to figure out a truly 
portable way of getting a high resolution tick count.

Unix isn't a real-time OS. When it was written, one second was a pretty 
short unit of time, and the smallest unit handled in many cases (e.g. 
sleep, date and the strftime() subroutine). With Unix computers now 
10,000 times faster, where one second resolution was adequate in the 
past, something a bit higher would make sense now. It seems like there 
isn't a clean way to do it using the widely supported Bourne shell (of 
which bash is a clone with backward compatibility). I was hoping there 
was a trick I wasn't aware of, but it seems not.

Linux has an extra strftime() macro %N (IIRC) that somehow gets the 
fractions of a second, although it's hard to see how as the input is a 
Unix time_t (i.e. one second resolution). As Steve O'Hara-Smith 
<steve@sohara.org> pointed out, there's a FreeBSD-specific tick count 
available as a kernel state variable, which allows a solution but 
requires conditional code in the script.

Newer versions of BSD have a replacement function called gettimeofday(), 
that passes a timeval structure containing a time_t and the time into 
the current second to microsecond resolution. Before that there was an 
ftime() library routine  from about Unix Version 7, which used a timeb 
structure that  included milliseconds instead (16-bit, see?). I'm pretty 
sure Linux supports gettimeofday() too.

So - if you're writing in 'C' you can get good resolution; if you're 
using a shell script it seems like you're out of luck if you want 
something portable. Unless there is a trick we've all missed.

Regards, Frank.


--------------V1NuJ2U88b7LRjHHXKm1eDbJ
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 18/07/2022 14:45, Tom Browder wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAFMGiz8NcH1BMiRkftz67qd=6jicvPzrfagr40hSN94i87jxVw@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div><br>
      </div>
      <div><br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Tue, Jul 12, 2022 at
            03:09 Frank Leonhardt &lt;<a
              href="mailto:freebsd-doc@fjl.co.uk" moz-do-not-send="true"
              class="moz-txt-link-freetext">freebsd-doc@fjl.co.uk</a>&gt;
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">I thought
            this would be easy, but it's not!<br>
            <br>
            I can get the time since the epoch to the nearest second
            (date +%s), but <br>
            nothing more accurate. This was probably good enough in the
            1970s but I <br>
            think it's reasonable to want a better resolution even in a
            shell script.</blockquote>
          <div dir="auto"><br>
          </div>
          <div dir="auto">I’m a wannabe FreeBSD user lurking here. Can
            you tell us more about your use case?</div>
          <div dir="auto"><br>
          </div>
          <div dir="auto">(Spoiler alert:  I’m a long time Unix/Linux
            user who now relies mostly on Raku for other than very
            simple bash scripts.)</div>
          <div dir="auto"><br>
          </div>
        </div>
      </div>
    </blockquote>
    <p>There is no use case here, other than trying to figure out a
      truly portable way of getting a high resolution tick count.</p>
    <p>Unix isn't a real-time OS. When it was written, one second was a
      pretty short unit of time, and the smallest unit handled in many
      cases (e.g. sleep, date and the strftime() subroutine). With Unix
      computers now 10,000 times faster, where one second resolution was
      adequate in the past, something a bit higher would make sense now.
      It seems like there isn't a clean way to do it using the widely
      supported Bourne shell (of which bash is a clone with backward
      compatibility). I was hoping there was a trick I wasn't aware of,
      but it seems not.<br>
    </p>
    <p>Linux has an extra strftime() macro %N (IIRC) that somehow gets
      the fractions of a second, although it's hard to see how as the
      input is a Unix time_t (i.e. one second resolution). As Steve
      O'Hara-Smith <a class="moz-txt-link-rfc2396E" href="mailto:steve@sohara.org">&lt;steve@sohara.org&gt;</a> pointed out, there's a
      FreeBSD-specific tick count available as a kernel state variable,
      which allows a solution but requires conditional code in the
      script.</p>
    <p>Newer versions of BSD have a replacement function called
      gettimeofday(), that passes a timeval structure containing a
      time_t and the time into the current second to microsecond
      resolution. Before that there was an ftime() library routine  from
      about Unix Version 7, which used a timeb structure that  included
      milliseconds instead (16-bit, see?). I'm pretty sure Linux
      supports gettimeofday() too.<br>
    </p>
    <p>So - if you're writing in 'C' you can get good resolution; if
      you're using a shell script it seems like you're out of luck if
      you want something portable. Unless there is a trick we've all
      missed.</p>
    <p>Regards, Frank.</p>
    <p><br>
    </p>
  </body>
</html>

--------------V1NuJ2U88b7LRjHHXKm1eDbJ--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?b764d6fb-0e14-ad7f-4d70-25d066591d4c>