From nobody Tue Jul 19 14:08:12 2022 X-Original-To: questions@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4LnLJr4RPQz4XNhR for ; Tue, 19 Jul 2022 14:08:12 +0000 (UTC) (envelope-from freebsd-doc@fjl.co.uk) Received: from bs1.fjl.org.uk (bs1.fjl.org.uk [84.45.41.196]) by mx1.freebsd.org (Postfix) with ESMTP id 4LnLJq52xVz3Y4g for ; Tue, 19 Jul 2022 14:08:11 +0000 (UTC) (envelope-from freebsd-doc@fjl.co.uk) Received: from [192.168.1.150] (host86-177-85-20.range86-177.btcentralplus.com [86.177.85.20]) (authenticated bits=0) by bs1.fjl.org.uk (8.14.4/8.14.4) with ESMTP id 26JE8BeP076846 for ; Tue, 19 Jul 2022 15:08:11 +0100 (BST) (envelope-from freebsd-doc@fjl.co.uk) Content-Type: multipart/alternative; boundary="------------V1NuJ2U88b7LRjHHXKm1eDbJ" Message-ID: Date: Tue, 19 Jul 2022 15:08:12 +0100 List-Id: User questions List-Archive: https://lists.freebsd.org/archives/freebsd-questions List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-questions@freebsd.org X-BeenThere: freebsd-questions@freebsd.org MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: How do get elapsed time in milliseconds in a shell script? Content-Language: en-GB To: questions@freebsd.org References: <4c98bb6d-a128-d10b-a896-6af11c06d41c@fjl.co.uk> From: Frank Leonhardt In-Reply-To: X-Rspamd-Queue-Id: 4LnLJq52xVz3Y4g X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org; dkim=none; dmarc=none; spf=pass (mx1.freebsd.org: domain of freebsd-doc@fjl.co.uk designates 84.45.41.196 as permitted sender) smtp.mailfrom=freebsd-doc@fjl.co.uk X-Spamd-Result: default: False [-2.20 / 15.00]; SUBJECT_ENDS_QUESTION(1.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_SHORT(-1.00)[-1.000]; NEURAL_HAM_LONG(-1.00)[-0.998]; R_SPF_ALLOW(-0.20)[+ip4:84.45.41.196:c]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; RCVD_NO_TLS_LAST(0.10)[]; ARC_NA(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:~]; ASN(0.00)[asn:25577, ipnet:84.45.0.0/17, country:GB]; R_DKIM_NA(0.00)[]; MLMMJ_DEST(0.00)[questions@freebsd.org]; DMARC_NA(0.00)[fjl.co.uk]; RCPT_COUNT_ONE(0.00)[1]; FROM_HAS_DN(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_NONE(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[questions@freebsd.org]; RCVD_COUNT_TWO(0.00)[2] X-ThisMailContainsUnwantedMimeParts: N 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 > 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 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
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--