From 1a9373bc570cf408cecdfab5d531e8041f354a54 Mon Sep 17 00:00:00 2001 From: Dave Cheney Date: Thu, 31 Mar 2016 11:58:19 +1100 Subject: [PATCH] cmd/compile/internal/gc: avoid append when building Type fields MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit As a followup to CL 21296, avoid append operations when constructing the fields of a Type if the length is known beforehand This also includes some small scoping driveby cleanups, and a change to tointerface0 to avoid iterating over the field list twice. compilebench shows a very small reduction in allocations. name old time/op new time/op delta Template 364ms ± 5% 363ms ± 4% ~ (p=0.945 n=20+19) Unicode 182ms ±11% 185ms ±12% ~ (p=0.445 n=20+20) GoTypes 1.14s ± 2% 1.14s ± 3% ~ (p=0.221 n=20+20) Compiler 5.85s ± 2% 5.84s ± 2% ~ (p=0.369 n=20+20) name old alloc/op new alloc/op delta Template 56.7MB ± 0% 56.7MB ± 0% -0.04% (p=0.000 n=20+20) Unicode 38.3MB ± 0% 38.3MB ± 0% ~ (p=0.728 n=20+19) GoTypes 180MB ± 0% 180MB ± 0% -0.02% (p=0.000 n=20+20) Compiler 812MB ± 0% 812MB ± 0% -0.02% (p=0.000 n=19+20) name old allocs/op new allocs/op delta Template 482k ± 0% 480k ± 0% -0.34% (p=0.000 n=20+20) Unicode 377k ± 0% 377k ± 0% -0.04% (p=0.010 n=20+20) GoTypes 1.36M ± 0% 1.35M ± 0% -0.24% (p=0.000 n=20+20) Compiler 5.47M ± 0% 5.46M ± 0% -0.11% (p=0.000 n=20+18) Change-Id: Ibb4c40229fa3816acd8de98ba41d1571a2aabacf Reviewed-on: https://go-review.googlesource.com/21352 Reviewed-by: Brad Fitzpatrick Run-TryBot: Dave Cheney --- src/cmd/compile/internal/gc/dcl.go | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 7adaa0ea2d..6e45231c1a 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -296,7 +296,6 @@ func constiter(vl []*Node, t *Node, cl []*Node) []*Node { } clcopy := listtreecopy(cl, lno) - var c *Node var vv []*Node for _, v := range vl { if len(clcopy) == 0 { @@ -304,7 +303,7 @@ func constiter(vl []*Node, t *Node, cl []*Node) []*Node { break } - c = clcopy[0] + c := clcopy[0] clcopy = clcopy[1:] v.Op = OLITERAL @@ -580,8 +579,7 @@ func funcargs(nt *Node) { } } - var n *Node - for _, n = range nt.List.Slice() { + for _, n := range nt.List.Slice() { if n.Op != ODCLFIELD { Fatalf("funcargs in %v", Oconv(n.Op, 0)) } @@ -599,7 +597,7 @@ func funcargs(nt *Node) { // declare the out arguments. gen := nt.List.Len() var i int = 0 - for _, n = range nt.Rlist.Slice() { + for _, n := range nt.Rlist.Slice() { if n.Op != ODCLFIELD { Fatalf("funcargs out %v", Oconv(n.Op, 0)) } @@ -817,13 +815,13 @@ func tostruct0(t *Type, l []*Node) { Fatalf("struct expected") } - var fields []*Field - for _, n := range l { + fields := make([]*Field, len(l)) + for i, n := range l { f := structfield(n) if f.Broke { t.Broke = true } - fields = append(fields, f) + fields[i] = f } t.SetFields(fields) @@ -838,8 +836,8 @@ func tofunargs(l []*Node) *Type { t := typ(TSTRUCT) t.Funarg = true - var fields []*Field - for _, n := range l { + fields := make([]*Field, len(l)) + for i, n := range l { f := structfield(n) f.Funarg = true @@ -850,7 +848,7 @@ func tofunargs(l []*Node) *Type { if f.Broke { t.Broke = true } - fields = append(fields, f) + fields[i] = f } t.SetFields(fields) return t @@ -953,15 +951,12 @@ func tointerface0(t *Type, l []*Node) *Type { } else { fields = append(fields, f) } - } - sort.Sort(methcmp(fields)) - t.SetFields(fields) - - for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() { if f.Broke { t.Broke = true } } + sort.Sort(methcmp(fields)) + t.SetFields(fields) checkdupfields("method", t) checkwidth(t) -- 2.48.1