]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: optimize siftupTimer and siftdownTimer a bit
authorAliaksandr Valialkin <valyala@gmail.com>
Tue, 12 Sep 2017 11:04:34 +0000 (14:04 +0300)
committerIan Lance Taylor <iant@golang.org>
Tue, 12 Sep 2017 17:25:00 +0000 (17:25 +0000)
Write the moving timer only once, since it is overwritten
by swapped timers on all the iterations except the last one.

Additionally, explicitly pass timers heap into siftupTimer
and siftdownTimer in order to make the code more clear.

Relevant benchmark results on linux/amd64:

Stop                      700µs ± 7%   608µs ± 1%  -13.13%  (p=0.000 n=10+10)
Stop-2                    440µs ± 4%   376µs ± 4%  -14.48%  (p=0.000 n=10+10)
Stop-4                    339µs ± 2%   330µs ± 3%   -2.66%  (p=0.015 n=10+10)
SimultaneousAfterFunc     702µs ± 9%   709µs ± 1%     ~     (p=0.436 n=9+9)
SimultaneousAfterFunc-2   573µs ± 2%   546µs ± 2%   -4.71%  (p=0.000 n=10+10)
SimultaneousAfterFunc-4   387µs ± 1%   368µs ± 1%   -4.89%  (p=0.000 n=8+10)
StartStop                 268µs ± 0%   270µs ± 0%   +0.91%  (p=0.000 n=9+9)
StartStop-2               155µs ± 6%   145µs ± 6%   -6.70%  (p=0.000 n=10+10)
StartStop-4               125µs ± 1%   124µs ± 1%     ~     (p=0.065 n=10+9)

Change-Id: I3685835b5e3e82844e2e5e73ee03a1e22100bf0e
Reviewed-on: https://go-review.googlesource.com/63110
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/time.go

index 6bfa6ba16084af4bb8d3bec2a9c36d5f264a4ee4..b9454d6e2b9f7bd1791098256d07d752d147bd97 100644 (file)
@@ -142,7 +142,7 @@ func (tb *timersBucket) addtimerLocked(t *timer) {
        }
        t.i = len(tb.t)
        tb.t = append(tb.t, t)
-       tb.siftupTimer(t.i)
+       siftupTimer(tb.t, t.i)
        if t.i == 0 {
                // siftup moved to top: new earliest deadline.
                if tb.sleeping {
@@ -182,8 +182,8 @@ func deltimer(t *timer) bool {
        tb.t[last] = nil
        tb.t = tb.t[:last]
        if i != last {
-               tb.siftupTimer(i)
-               tb.siftdownTimer(i)
+               siftupTimer(tb.t, i)
+               siftdownTimer(tb.t, i)
        }
        unlock(&tb.lock)
        return true
@@ -212,7 +212,7 @@ func timerproc(tb *timersBucket) {
                        if t.period > 0 {
                                // leave in heap but adjust next time to fire
                                t.when += t.period * (1 + -delta/t.period)
-                               tb.siftdownTimer(0)
+                               siftdownTimer(tb.t, 0)
                        } else {
                                // remove from heap
                                last := len(tb.t) - 1
@@ -223,7 +223,7 @@ func timerproc(tb *timersBucket) {
                                tb.t[last] = nil
                                tb.t = tb.t[:last]
                                if last > 0 {
-                                       tb.siftdownTimer(0)
+                                       siftdownTimer(tb.t, 0)
                                }
                                t.i = -1 // mark as removed
                        }
@@ -317,8 +317,7 @@ func timeSleepUntil() int64 {
 
 // Heap maintenance algorithms.
 
-func (tb *timersBucket) siftupTimer(i int) {
-       t := tb.t
+func siftupTimer(t []*timer, i int) {
        when := t[i].when
        tmp := t[i]
        for i > 0 {
@@ -328,14 +327,15 @@ func (tb *timersBucket) siftupTimer(i int) {
                }
                t[i] = t[p]
                t[i].i = i
-               t[p] = tmp
-               t[p].i = p
                i = p
        }
+       if tmp != t[i] {
+               t[i] = tmp
+               t[i].i = i
+       }
 }
 
-func (tb *timersBucket) siftdownTimer(i int) {
-       t := tb.t
+func siftdownTimer(t []*timer, i int) {
        n := len(t)
        when := t[i].when
        tmp := t[i]
@@ -366,10 +366,12 @@ func (tb *timersBucket) siftdownTimer(i int) {
                }
                t[i] = t[c]
                t[i].i = i
-               t[c] = tmp
-               t[c].i = c
                i = c
        }
+       if tmp != t[i] {
+               t[i] = tmp
+               t[i].i = i
+       }
 }
 
 // Entry points for net, time to call nanotime.