Commit 1a9373bc authored by Dave Cheney's avatar Dave Cheney

cmd/compile/internal/gc: avoid append when building Type fields

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/21352Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Dave Cheney <dave@cheney.net>
parent ea5091fc
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment