mirror of https://github.com/golang/go.git
cmd/compile: do not allocate bucket for non-escaping map
For map with hint larger than BUCKETSIZE, makemap ignore allocated
bucket and allocate buckets itself. So do not allocate bucket in
this case, save us the cost of zeroing+assignment to the bucket.
name old time/op new time/op delta
NewEmptyMap-12 3.89ns ± 4% 3.88ns ± 2% ~ (p=0.939 n=19+20)
NewSmallMap-12 23.3ns ± 3% 23.1ns ± 2% ~ (p=0.307 n=18+17)
NewEmptyMapHintLessThan8-12 6.43ns ± 3% 6.31ns ± 2% -1.72% (p=0.000 n=19+18)
NewEmptyMapHintGreaterThan8-12 159ns ± 2% 150ns ± 1% -5.79% (p=0.000 n=20+18)
Benchmark run with commit ab7c174 reverted, see #38314.
Fixes #20184
Change-Id: Ic021f57454c3a0dd50601d73bbd77b8faf8d93b6
Reviewed-on: https://go-review.googlesource.com/c/go/+/227458
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
346d7d273c
commit
98b6c6aca6
|
|
@ -1247,12 +1247,23 @@ opswitch:
|
|||
// are stored with an indirection. So max bucket size is 2048+eps.
|
||||
if !Isconst(hint, CTINT) ||
|
||||
hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 {
|
||||
|
||||
// In case hint is larger than BUCKETSIZE runtime.makemap
|
||||
// will allocate the buckets on the heap, see #20184
|
||||
//
|
||||
// if hint <= BUCKETSIZE {
|
||||
// var bv bmap
|
||||
// b = &bv
|
||||
// h.buckets = b
|
||||
// }
|
||||
|
||||
nif := nod(OIF, nod(OLE, hint, nodintconst(BUCKETSIZE)), nil)
|
||||
nif.SetLikely(true)
|
||||
|
||||
// var bv bmap
|
||||
bv := temp(bmap(t))
|
||||
|
||||
zero = nod(OAS, bv, nil)
|
||||
zero = typecheck(zero, ctxStmt)
|
||||
init.Append(zero)
|
||||
nif.Nbody.Append(zero)
|
||||
|
||||
// b = &bv
|
||||
b := nod(OADDR, bv, nil)
|
||||
|
|
@ -1260,8 +1271,11 @@ opswitch:
|
|||
// h.buckets = b
|
||||
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
|
||||
na := nod(OAS, nodSym(ODOT, h, bsym), b)
|
||||
na = typecheck(na, ctxStmt)
|
||||
init.Append(na)
|
||||
nif.Nbody.Append(na)
|
||||
|
||||
nif = typecheck(nif, ctxStmt)
|
||||
nif = walkstmt(nif)
|
||||
init.Append(nif)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -513,3 +513,22 @@ func BenchmarkMapInterfacePtr(b *testing.B) {
|
|||
BoolSink = m[key]
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
hintLessThan8 = 7
|
||||
hintGreaterThan8 = 32
|
||||
)
|
||||
|
||||
func BenchmarkNewEmptyMapHintLessThan8(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = make(map[int]int, hintLessThan8)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewEmptyMapHintGreaterThan8(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = make(map[int]int, hintGreaterThan8)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue