mirror of
https://github.com/golang/go
synced 2024-11-17 00:04:40 -07:00
encoding/gob: use MakeMapWithSize when decoding map
This allows to pre-allocate the final size of the hashmap and avoid re-allocating as we insert entries. Furthermore for the current implementation of the hashmap it allows avoiding several rounds of evacuating hashmap entries after each re-allocation. DecodeComplex128Slice-8 51.9µs ± 1% 51.9µs ± 2% ~ (p=0.797 n=30+29) DecodeFloat64Slice-8 31.5µs ± 2% 31.6µs ± 2% ~ (p=0.050 n=28+28) DecodeInt32Slice-8 32.0µs ± 2% 31.9µs ± 3% ~ (p=0.666 n=29+28) DecodeStringSlice-8 57.7µs ± 2% 57.8µs ± 3% ~ (p=0.780 n=27+30) DecodeInterfaceSlice-8 498µs ± 2% 495µs ± 2% ~ (p=0.070 n=28+29) DecodeMap-8 300µs ± 2% 230µs ± 5% -23.31% (p=0.000 n=27+27) Updates #19525 Change-Id: Ia7233da49f05bae7a86c064d9ecebca966f5f2f7 Reviewed-on: https://go-review.googlesource.com/40113 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
f9531448b8
commit
f504bc0055
@ -557,11 +557,10 @@ func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Va
|
||||
// Because the internals of maps are not visible to us, we must
|
||||
// use reflection rather than pointer magic.
|
||||
func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {
|
||||
if value.IsNil() {
|
||||
// Allocate map.
|
||||
value.Set(reflect.MakeMap(mtyp))
|
||||
}
|
||||
n := int(state.decodeUint())
|
||||
if value.IsNil() {
|
||||
value.Set(reflect.MakeMapWithSize(mtyp, n))
|
||||
}
|
||||
keyIsPtr := mtyp.Key().Kind() == reflect.Ptr
|
||||
elemIsPtr := mtyp.Elem().Kind() == reflect.Ptr
|
||||
keyInstr := &decInstr{keyOp, 0, nil, ovfl}
|
||||
|
@ -289,7 +289,7 @@ func BenchmarkDecodeInterfaceSlice(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkDecodeMap(b *testing.B) {
|
||||
count := 10000
|
||||
count := 1000
|
||||
m := make(map[int]int, count)
|
||||
for i := 0; i < count; i++ {
|
||||
m[i] = i
|
||||
@ -303,7 +303,7 @@ func BenchmarkDecodeMap(b *testing.B) {
|
||||
bbuf := benchmarkBuf{data: buf.Bytes()}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
rm := make(map[int]int, 0)
|
||||
var rm map[int]int
|
||||
bbuf.reset()
|
||||
dec := NewDecoder(&bbuf)
|
||||
err := dec.Decode(&rm)
|
||||
|
Loading…
Reference in New Issue
Block a user