]> Cypherpunks repositories - gostls13.git/commitdiff
time: speed up Since and Until
authorDmitry Vyukov <dvyukov@google.com>
Wed, 31 Oct 2018 16:36:51 +0000 (17:36 +0100)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 2 Nov 2018 12:50:18 +0000 (12:50 +0000)
time.now is somewhat expensive (much more expensive than nanotime),
in the common case when Time has monotonic time we don't actually
need to call time.now in Since/Until as we can do calculation
based purely on monotonic times.

name                  old time/op  new time/op  delta
TCP4OneShotTimeout-6  17.0µs ± 0%  17.1µs ± 1%     ~     (p=0.151 n=5+5)
SetReadDeadline-6      261ns ± 0%   234ns ± 1%  -10.35%  (p=0.008 n=5+5)

Benchmark that only calls Until:

benchmark            old ns/op     new ns/op     delta
BenchmarkUntil       54.0          29.5          -45.37%

Update #25729

Change-Id: I5ac5af3eb1fe9f583cf79299f10b84501b1a0d7d
Reviewed-on: https://go-review.googlesource.com/c/146341
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/time/time.go

index 144f2fe73df2bec4c7aabd76d875e57a09bc5e92..4241a6241bf52c136f087da4fb5dac2081bb6055 100644 (file)
@@ -908,13 +908,27 @@ func (t Time) Sub(u Time) Duration {
 // Since returns the time elapsed since t.
 // It is shorthand for time.Now().Sub(t).
 func Since(t Time) Duration {
-       return Now().Sub(t)
+       var now Time
+       if t.wall&hasMonotonic != 0 {
+               // Common case optimization: if t has monotomic time, then Sub will use only it.
+               now = Time{hasMonotonic, runtimeNano() - startNano, nil}
+       } else {
+               now = Now()
+       }
+       return now.Sub(t)
 }
 
 // Until returns the duration until t.
 // It is shorthand for t.Sub(time.Now()).
 func Until(t Time) Duration {
-       return t.Sub(Now())
+       var now Time
+       if t.wall&hasMonotonic != 0 {
+               // Common case optimization: if t has monotomic time, then Sub will use only it.
+               now = Time{hasMonotonic, runtimeNano() - startNano, nil}
+       } else {
+               now = Now()
+       }
+       return t.Sub(now)
 }
 
 // AddDate returns the time corresponding to adding the