]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: reuse []Flow
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 11 Jun 2015 20:56:28 +0000 (13:56 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 22 Feb 2016 18:22:48 +0000 (18:22 +0000)
Benchmarked using compilebench on a quiet
but rather old OS X laptop.

Benchmarks from others would be welcome,
since the numbers look too good to be true.

name      old time/op    new time/op    delta
Template     331ms ± 9%     303ms ± 4%   -8.25%  (p=0.000 n=24+24)
GoTypes      946ms ± 4%     888ms ± 3%   -6.17%  (p=0.000 n=24+25)
Compiler     3.20s ± 1%     3.10s ± 2%   -3.07%  (p=0.000 n=24+25)

name      old alloc/op   new alloc/op   delta
Template    72.5MB ± 0%    61.8MB ± 0%  -14.76%  (p=0.000 n=25+24)
GoTypes      224MB ± 0%     189MB ± 0%  -15.65%  (p=0.000 n=25+25)
Compiler     695MB ± 0%     561MB ± 0%  -19.26%  (p=0.000 n=25+25)

name      old allocs/op  new allocs/op  delta
Template      498k ± 0%      497k ± 0%   -0.21%  (p=0.000 n=25+23)
GoTypes      1.47M ± 0%     1.47M ± 0%   -0.25%  (p=0.000 n=25+25)
Compiler     4.09M ± 0%     4.08M ± 0%   -0.18%  (p=0.000 n=25+23)

Change-Id: I2394bc748128d721863453257fa5756c410f7898
Reviewed-on: https://go-review.googlesource.com/19771
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/popt.go

index 4d71ab643da4994bd1e479ecafa539935660b3b8..b70822284557a49a31f7648a0d2e09d72048f331 100644 (file)
@@ -241,6 +241,19 @@ var flowmark int
 // will not have flow graphs and consequently will not be optimized.
 const MaxFlowProg = 50000
 
+var ffcache []Flow // reusable []Flow, to reduce allocation
+
+func growffcache(n int) {
+       if n > cap(ffcache) {
+               n = (n * 5) / 4
+               if n > MaxFlowProg {
+                       n = MaxFlowProg
+               }
+               ffcache = make([]Flow, n)
+       }
+       ffcache = ffcache[:n]
+}
+
 func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
        // Count and mark instructions to annotate.
        nf := 0
@@ -268,7 +281,9 @@ func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
 
        // Allocate annotations and assign to instructions.
        graph := new(Graph)
-       ff := make([]Flow, nf)
+
+       growffcache(nf)
+       ff := ffcache
        start := &ff[0]
        id := 0
        var last *Flow
@@ -331,6 +346,10 @@ func Flowend(graph *Graph) {
                f.Prog.Info.Flags = 0 // drop cached proginfo
                f.Prog.Opt = nil
        }
+       clear := ffcache[:graph.Num]
+       for i := range clear {
+               clear[i] = Flow{}
+       }
 }
 
 // find looping structure