]> Cypherpunks repositories - gostls13.git/commitdiff
time: make time.Since a few nanoseconds faster
authorRuss Cox <rsc@golang.org>
Thu, 10 Aug 2023 15:56:53 +0000 (11:56 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 11 Aug 2023 15:26:40 +0000 (15:26 +0000)
time.Since(base) is an idiom that can be used to read the system
monotonic time as efficiently as possible, when that matters.
The current code structure adds a few nanoseconds on top of
the 15-20ns the time read already takes. Remove those few.

After this CL, there is no reason at all for anyone to
//go:linkname runtime.nanotime1 instead.

Came up while investigating #61765.

Change-Id: Ic9e688af039babfc2a5a8e67dcbb02847a5eb686
Reviewed-on: https://go-review.googlesource.com/c/go/+/518336
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
src/time/time.go

index 00c6d6423f950a82987a551acb0b89f6c0b5b8ff..8570635e2a3d145d8824dc1c3ec1f6c8fb1414e7 100644 (file)
@@ -891,16 +891,7 @@ func (t Time) Add(d Duration) Time {
 // To compute t-d for a duration d, use t.Add(-d).
 func (t Time) Sub(u Time) Duration {
        if t.wall&u.wall&hasMonotonic != 0 {
-               te := t.ext
-               ue := u.ext
-               d := Duration(te - ue)
-               if d < 0 && te > ue {
-                       return maxDuration // t - u is positive out of range
-               }
-               if d > 0 && te < ue {
-                       return minDuration // t - u is negative out of range
-               }
-               return d
+               return subMono(t.ext, u.ext)
        }
        d := Duration(t.sec()-u.sec())*Second + Duration(t.nsec()-u.nsec())
        // Check for overflow or underflow.
@@ -914,17 +905,25 @@ func (t Time) Sub(u Time) Duration {
        }
 }
 
+func subMono(t, u int64) Duration {
+       d := Duration(t - u)
+       if d < 0 && t > u {
+               return maxDuration // t - u is positive out of range
+       }
+       if d > 0 && t < u {
+               return minDuration // t - u is negative out of range
+       }
+       return d
+}
+
 // Since returns the time elapsed since t.
 // It is shorthand for time.Now().Sub(t).
 func Since(t Time) Duration {
-       var now Time
        if t.wall&hasMonotonic != 0 {
                // Common case optimization: if t has monotonic time, then Sub will use only it.
-               now = Time{hasMonotonic, runtimeNano() - startNano, nil}
-       } else {
-               now = Now()
+               return subMono(runtimeNano()-startNano, t.ext)
        }
-       return now.Sub(t)
+       return Now().Sub(t)
 }
 
 // Until returns the duration until t.