From 06a78b57377ce63c7fca968af5056a3dec0a06bb Mon Sep 17 00:00:00 2001 From: Martin Möhrmann Date: Wed, 16 Aug 2017 23:36:58 +0200 Subject: cmd/compile: pass stack allocated bucket to makemap inside hmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit name old time/op new time/op delta NewEmptyMap 53.2ns ± 7% 48.0ns ± 5% -9.77% (p=0.000 n=20+20) NewSmallMap 111ns ± 1% 106ns ± 2% -3.78% (p=0.000 n=20+19) Change-Id: I979d21ab16eae9f6893873becca517db57e054b5 Reviewed-on: https://go-review.googlesource.com/56290 Run-TryBot: Martin Möhrmann TryBot-Result: Gobot Gobot Reviewed-by: Josh Bleecher Snyder --- src/runtime/hashmap.go | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src/runtime') diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index efb8a78024..852b65d1db 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -259,8 +259,8 @@ func (h *hmap) createOverflow() { // If the compiler has determined that the map or the first bucket // can be created on the stack, h and/or bucket may be non-nil. // If h != nil, the map can be created directly in h. -// If bucket != nil, bucket can be used as the first bucket. -func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap { +// If h.buckets != nil, bucket pointed to can be used as the first bucket. +func makemap(t *maptype, hint int64, h *hmap) *hmap { if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != t.hmap.size { println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size) throw("bad hmap size") @@ -312,34 +312,31 @@ func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap { throw("bad evacuatedN") } + // initialize Hmap + if h == nil { + h = (*hmap)(newobject(t.hmap)) + } + h.hash0 = fastrand() + // find size parameter which will hold the requested # of elements B := uint8(0) - for ; overLoadFactor(hint, B); B++ { + for overLoadFactor(hint, B) { + B++ } + h.B = B // allocate initial hash table // if B == 0, the buckets field is allocated lazily later (in mapassign) // If hint is large zeroing this memory could take a while. - buckets := bucket - var extra *mapextra - if B != 0 { + if h.B != 0 { var nextOverflow *bmap - buckets, nextOverflow = makeBucketArray(t, B) + h.buckets, nextOverflow = makeBucketArray(t, h.B) if nextOverflow != nil { - extra = new(mapextra) - extra.nextOverflow = nextOverflow + h.extra = new(mapextra) + h.extra.nextOverflow = nextOverflow } } - // initialize Hmap - if h == nil { - h = (*hmap)(newobject(t.hmap)) - } - h.B = B - h.extra = extra - h.hash0 = fastrand() - h.buckets = buckets - return h } @@ -1171,7 +1168,7 @@ func ismapkey(t *_type) bool { //go:linkname reflect_makemap reflect.makemap func reflect_makemap(t *maptype, cap int) *hmap { - return makemap(t, int64(cap), nil, nil) + return makemap(t, int64(cap), nil) } //go:linkname reflect_mapaccess reflect.mapaccess -- cgit v1.3-5-g9baa