Skip to content

Commit 98b6c6a

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 346d7d2 commit 98b6c6a

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

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

+19-5
Original file line numberDiff line numberDiff line change
@@ -1247,21 +1247,35 @@ opswitch:
12471247
// are stored with an indirection. So max bucket size is 2048+eps.
12481248
if !Isconst(hint, CTINT) ||
12491249
hint.Val().U.(*Mpint).CmpInt64(BUCKETSIZE) <= 0 {
1250+
1251+
// In case hint is larger than BUCKETSIZE runtime.makemap
1252+
// will allocate the buckets on the heap, see #20184
1253+
//
1254+
// if hint <= BUCKETSIZE {
1255+
// var bv bmap
1256+
// b = &bv
1257+
// h.buckets = b
1258+
// }
1259+
1260+
nif := nod(OIF, nod(OLE, hint, nodintconst(BUCKETSIZE)), nil)
1261+
nif.SetLikely(true)
1262+
12501263
// var bv bmap
12511264
bv := temp(bmap(t))
1252-
12531265
zero = nod(OAS, bv, nil)
1254-
zero = typecheck(zero, ctxStmt)
1255-
init.Append(zero)
1266+
nif.Nbody.Append(zero)
12561267

12571268
// b = &bv
12581269
b := nod(OADDR, bv, nil)
12591270

12601271
// h.buckets = b
12611272
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
12621273
na := nod(OAS, nodSym(ODOT, h, bsym), b)
1263-
na = typecheck(na, ctxStmt)
1264-
init.Append(na)
1274+
nif.Nbody.Append(na)
1275+
1276+
nif = typecheck(nif, ctxStmt)
1277+
nif = walkstmt(nif)
1278+
init.Append(nif)
12651279
}
12661280
}
12671281

src/runtime/map_benchmark_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -513,3 +513,22 @@ func BenchmarkMapInterfacePtr(b *testing.B) {
513513
BoolSink = m[key]
514514
}
515515
}
516+
517+
var (
518+
hintLessThan8 = 7
519+
hintGreaterThan8 = 32
520+
)
521+
522+
func BenchmarkNewEmptyMapHintLessThan8(b *testing.B) {
523+
b.ReportAllocs()
524+
for i := 0; i < b.N; i++ {
525+
_ = make(map[int]int, hintLessThan8)
526+
}
527+
}
528+
529+
func BenchmarkNewEmptyMapHintGreaterThan8(b *testing.B) {
530+
b.ReportAllocs()
531+
for i := 0; i < b.N; i++ {
532+
_ = make(map[int]int, hintGreaterThan8)
533+
}
534+
}

0 commit comments

Comments
 (0)