]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/gc: avoid append when building Type fields
authorDave Cheney <dave@cheney.net>
Thu, 31 Mar 2016 00:58:19 +0000 (11:58 +1100)
committerDave Cheney <dave@cheney.net>
Thu, 31 Mar 2016 02:22:18 +0000 (02:22 +0000)
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 <bradfitz@golang.org>
Run-TryBot: Dave Cheney <dave@cheney.net>

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

index 7adaa0ea2d102e6f192f362aa0fcc34e60a46c15..6e45231c1a16cb160a1cdac1452445cf7f5ba56f 100644 (file)
@@ -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)