aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/map.go
AgeCommit message (Collapse)Author
2020-09-18reflect: use zero buffer to back the Value returned by ZeroKeith Randall
In the common case (<1KB types), no allocation is required by reflect.Zero. Also use memclr instead of memmove in Set when the source is known to be zero. Fixes #33136 Change-Id: Ic66871930fbb53328032e587153ebd12995ccf55 Reviewed-on: https://go-review.googlesource.com/c/go/+/192331 Trust: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com>
2020-09-07runtime: rotate map key seed on clearing up mapsCuong Manh Le
Same thing as CL 253020 did for map clear idiom. name old time/op new time/op delta MapDelete/Int32/100-12 30.0ns ± 1% 30.7ns ± 3% ~ (p=0.400 n=3+3) MapDelete/Int32/1000-12 26.6ns ± 2% 28.1ns ± 3% ~ (p=0.100 n=3+3) MapDelete/Int32/10000-12 28.6ns ± 1% 31.9ns ± 1% ~ (p=0.100 n=3+3) MapDelete/Int64/100-12 30.2ns ± 0% 32.1ns ± 3% ~ (p=0.100 n=3+3) MapDelete/Int64/1000-12 26.5ns ± 1% 27.5ns ± 3% ~ (p=0.100 n=3+3) MapDelete/Int64/10000-12 29.6ns ± 1% 29.3ns ± 1% ~ (p=0.300 n=3+3) MapDelete/Str/100-12 19.5ns ± 3% 19.6ns ± 2% ~ (p=0.800 n=3+3) MapDelete/Str/1000-12 31.6ns ± 1% 31.4ns ± 1% ~ (p=0.500 n=3+3) MapDelete/Str/10000-12 37.8ns ± 1% 37.1ns ± 1% ~ (p=0.100 n=3+3) MapDelete/Pointer/100-12 15.9ns ± 1% 16.8ns ± 9% ~ (p=0.200 n=3+3) MapDelete/Pointer/1000-12 26.9ns ± 1% 26.2ns ± 2% ~ (p=0.200 n=3+3) MapDelete/Pointer/10000-12 30.6ns ± 1% 30.7ns ± 4% ~ (p=0.700 n=3+3) Fixes #25237 Change-Id: I353cf44a2f6158549f0ef563d867f0844fec7095 Reviewed-on: https://go-review.googlesource.com/c/go/+/252940 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
2020-09-03runtime: opportunistically rotate map key seedBenjamin Barenblat
When clearing a map, reinitialize the hash seed with random data. This makes it more difficult for attackers to trigger pathological performance via repeated hash collisions. The extra reinitialization causes no statistically significant slowdown: name old time/op new time/op delta GoMapClear/Reflexive/1-12 18.3ns ± 0% 20.0ns ± 0% ~ (p=1.000 n=1+1) GoMapClear/Reflexive/10-12 18.2ns ± 0% 19.8ns ± 0% ~ (p=1.000 n=1+1) GoMapClear/Reflexive/100-12 44.6ns ± 0% 46.1ns ± 0% ~ (p=1.000 n=1+1) GoMapClear/Reflexive/1000-12 592ns ± 0% 592ns ± 0% ~ (all samples are equal) GoMapClear/Reflexive/10000-12 3.88µs ± 0% 3.88µs ± 0% ~ (p=1.000 n=1+1) GoMapClear/NonReflexive/1-12 62.7ns ± 0% 63.9ns ± 0% ~ (p=1.000 n=1+1) GoMapClear/NonReflexive/10-12 75.0ns ± 0% 76.1ns ± 0% ~ (p=1.000 n=1+1) GoMapClear/NonReflexive/100-12 203ns ± 0% 206ns ± 0% ~ (p=1.000 n=1+1) GoMapClear/NonReflexive/1000-12 2.33µs ± 0% 2.33µs ± 0% ~ (all samples are equal) GoMapClear/NonReflexive/10000-12 18.1µs ± 0% 18.1µs ± 0% ~ (p=1.000 n=1+1) Fixes #25237 Change-Id: I629a79dd7c562ba18bd94159673c3b9b653da643 Reviewed-on: https://go-review.googlesource.com/c/go/+/253020 Reviewed-by: Keith Randall <khr@golang.org>
2020-04-01runtime: fix typo in loadFactor commentmaronghe
Fixes #38174 Change-Id: Iacdbbcd0b4586302daf082e59d833b7aa58b1a6a GitHub-Last-Rev: f0c96819ebb9928879a03957244f2de655708cbb GitHub-Pull-Request: golang/go#38191 Reviewed-on: https://go-review.googlesource.com/c/go/+/226758 Reviewed-by: Alberto Donizetti <alb.donizetti@gmail.com>
2019-09-03cmd/compile,runtime: generate hash functions only for types which are map keysKeith Randall
Right now we generate hash functions for all types, just in case they are used as map keys. That's a lot of wasted effort and binary size for types which will never be used as a map key. Instead, generate hash functions only for types that we know are map keys. Just doing that is a bit too simple, since maps with an interface type as a key might have to hash any concrete key type that implements that interface. So for that case, implement hashing of such types at runtime (instead of with generated code). It will be slower, but only for maps with interface types as keys, and maybe only a bit slower as the aeshash time probably dominates the dispatch time. Reorg where we keep the equals and hash functions. Move the hash function from the key type to the map type, saving a field in every non-map type. That leaves only one function in the alg structure, so get rid of that and just keep the equal function in the type descriptor itself. cmd/go now has 10 generated hash functions, instead of 504. Makes cmd/go 1.0% smaller. Update #6853. Speed on non-interface keys is unchanged. Speed on interface keys is ~20% slower: name old time/op new time/op delta MapInterfaceString-8 23.0ns ±21% 27.6ns ±14% +20.01% (p=0.002 n=10+10) MapInterfacePtr-8 19.4ns ±16% 23.7ns ± 7% +22.48% (p=0.000 n=10+8) Change-Id: I7c2e42292a46b5d4e288aaec4029bdbb01089263 Reviewed-on: https://go-review.googlesource.com/c/go/+/191198 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com>
2019-08-29cmd/compile: refactor zero value size to be a constantAgniva De Sarker
Change-Id: I31dd4fb55d5974cd45de00148039d04f8a7d5cb3 Reviewed-on: https://go-review.googlesource.com/c/go/+/187257 Run-TryBot: Agniva De Sarker <agniva.quicksilver@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com>
2019-04-30all: refer to map elements as elements instead of valuesJosh Bleecher Snyder
The spec carefully and consistently uses "key" and "element" as map terminology. The implementation, not so much. This change attempts to make the implementation consistently hew to the spec's terminology. Beyond consistency, this has the advantage of avoid some confusion and naming collisions, since v and value are very generic and commonly used terms. I believe that I found all everything, but there are a lot of non-obvious places for these to hide, and grepping for them is hard. Hopefully this change changes enough of them that we will start using elem going forward. Any remaining hidden cases can be removed ad hoc as they are discovered. The only externally-facing part of this change is in package reflect, where there is a minor doc change and a function parameter name change. Updates #27167 Change-Id: I2f2d78f16c360dc39007b9966d5c2046a29d3701 Reviewed-on: https://go-review.googlesource.com/c/go/+/174523 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-03-31runtime: always mask shift amount regardless of architectureMichael Munday
Currently the shift amount is only masked on x86. Change it so it is masked on all architectures. In the worst case we generate a couple of extra instructions to perform the masking and in the best case we can elide overflow checks. This particular shift could also be replaced with a rotate instruction during optimization which would remove both the masking instructions and overflow checks on all architectures. Fixes #31165. Change-Id: I16b7a8800b4ba8813dc83735dfc59564e661d3b4 Reviewed-on: https://go-review.googlesource.com/c/go/+/170122 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2019-03-28runtime: fix minor doc typoJosh Bleecher Snyder
Change-Id: I0a1ebaf41a1bc95508fd9aa782953ddca5ef49c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/169724 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-03-27sort, internal/reflectlite: flesh out reflectlite enough for use by sortBrad Fitzpatrick
Now the net package is back to no longer depending on unicode. And lock that in with a test. Fixes #30440 Change-Id: I18b89b02f7d96488783adc07308da990f505affd Reviewed-on: https://go-review.googlesource.com/c/go/+/169137 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2019-03-25runtime: remove kindNoPointersKeith Randall
We already have the ptrdata field in a type, which encodes exactly the same information that kindNoPointers does. My problem with kindNoPointers is that it often leads to double-negative code like: t.kind & kindNoPointers != 0 Much clearer is: t.ptrdata == 0 Update #27167 Change-Id: I92307d7f018a6bbe3daca4a4abb4225e359349b1 Reviewed-on: https://go-review.googlesource.com/c/go/+/169157 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-12-29runtime: panic on uncomparable map key, even if map is emptyKeith Randall
Reorg map flags a bit so we don't need any extra space for the extra flag. Fixes #23734 Change-Id: I436812156240ae90de53d0943fe1aabf3ea37417 Reviewed-on: https://go-review.googlesource.com/c/155918 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-11-13runtime: during map delete, update entries after new last elementKeith Randall
When we delete an element, and it was the last element in the bucket, update the slots between the new last element and the old last element with the marker that says "no more elements beyond here". Change-Id: I8efeeddf4c9b9fc491c678f84220a5a5094c9c76 Reviewed-on: https://go-review.googlesource.com/c/142438 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-10-31runtime: exit early when scanning map bucketsKeith Randall
Divide the "empty" slot state into two, "emptyOne" and "emptyRest". emptyOne means just that slot is empty. emptyRest means all subsequent slots in that bucket are empty and the overflow pointer is nil. When scanning a bucket, we can often stop at emptyRest, reducing the total work we have to do. (This is similar to how tombstones work in open addressing.) Ideally on delete we have to figure out whether to zero the slot with an emptyOne or emptyRest marker. For now, we choose the safe but non-optimal choice. (Fix in subsequent CL?) This is a simpler CL than some others we've tried, including my CL sequence 11835[5-8] and Ilya's CL 115616. Update #19495 name old time/op new time/op delta MegMap 8.96ns ± 2% 8.74ns ± 6% -2.44% (p=0.020 n=10+10) MegOneMap 8.91ns ± 2% 5.53ns ± 2% -37.99% (p=0.000 n=10+10) MegEqMap 46.0µs ± 1% 45.8µs ± 3% ~ (p=0.315 n=9+10) MegEmptyMap 2.50ns ± 0% 2.50ns ± 2% ~ (p=0.957 n=8+10) SmallStrMap 8.54ns ± 1% 8.71ns ± 2% +2.01% (p=0.000 n=10+10) MapStringKeysEight_16 8.61ns ± 3% 8.71ns ± 3% +1.20% (p=0.026 n=9+9) MapStringKeysEight_32 8.54ns ± 2% 8.97ns ± 1% +5.05% (p=0.000 n=10+9) MapStringKeysEight_64 8.66ns ± 2% 8.99ns ± 2% +3.87% (p=0.000 n=10+10) MapStringKeysEight_1M 8.57ns ± 2% 8.95ns ± 2% +4.51% (p=0.000 n=10+9) IntMap 6.69ns ± 1% 7.46ns ± 1% +11.60% (p=0.000 n=9+9) MapFirst/1 3.69ns ± 1% 3.63ns ± 3% -1.52% (p=0.040 n=10+10) MapFirst/2 3.70ns ± 2% 3.63ns ± 2% -1.95% (p=0.001 n=9+9) MapFirst/3 3.74ns ± 2% 3.66ns ± 2% -2.12% (p=0.000 n=8+10) MapFirst/4 3.71ns ± 2% 3.66ns ± 4% ~ (p=0.073 n=9+10) MapFirst/5 3.69ns ± 1% 3.62ns ± 2% -1.88% (p=0.000 n=9+10) MapFirst/6 3.68ns ± 2% 3.62ns ± 1% -1.83% (p=0.001 n=10+9) MapFirst/7 3.67ns ± 1% 3.60ns ± 1% -1.98% (p=0.000 n=10+8) MapFirst/8 3.68ns ± 2% 3.61ns ± 2% -1.87% (p=0.000 n=10+10) MapFirst/9 8.03ns ± 4% 7.89ns ± 2% -1.76% (p=0.007 n=10+10) MapFirst/10 7.99ns ± 2% 7.86ns ± 3% -1.64% (p=0.009 n=9+10) MapFirst/11 7.96ns ± 1% 7.80ns ± 2% -2.01% (p=0.000 n=10+10) MapFirst/12 7.96ns ± 1% 7.82ns ± 1% -1.67% (p=0.000 n=10+10) MapFirst/13 8.06ns ± 3% 7.92ns ± 3% ~ (p=0.055 n=10+10) MapFirst/14 7.95ns ± 1% 7.80ns ± 1% -1.88% (p=0.000 n=10+9) MapFirst/15 8.01ns ± 2% 7.80ns ± 2% -2.57% (p=0.000 n=10+10) MapFirst/16 8.05ns ± 2% 7.90ns ± 2% -1.84% (p=0.005 n=9+10) MapMid/1 4.00ns ± 1% 3.94ns ± 2% -1.30% (p=0.021 n=8+9) MapMid/2 4.39ns ± 2% 4.32ns ± 4% ~ (p=0.128 n=10+10) MapMid/3 4.40ns ± 2% 4.27ns ± 2% -2.93% (p=0.000 n=10+9) MapMid/4 4.76ns ± 2% 4.65ns ± 1% -2.26% (p=0.000 n=10+9) MapMid/5 4.76ns ± 1% 4.65ns ± 1% -2.27% (p=0.000 n=10+10) MapMid/6 5.11ns ± 2% 4.98ns ± 2% -2.55% (p=0.000 n=10+10) MapMid/7 5.12ns ± 1% 5.01ns ± 3% -2.02% (p=0.003 n=9+9) MapMid/8 5.71ns ± 3% 5.97ns ± 1% +4.51% (p=0.000 n=10+9) MapMid/9 8.72ns ±10% 8.89ns ±10% ~ (p=0.458 n=9+10) MapMid/10 10.1ns ±15% 9.6ns ± 7% ~ (p=0.080 n=9+10) MapMid/11 9.88ns ±10% 9.44ns ±11% ~ (p=0.065 n=10+10) MapMid/12 9.90ns ±13% 10.04ns ± 9% ~ (p=1.000 n=10+8) MapMid/13 9.67ns ±14% 10.23ns ±10% ~ (p=0.209 n=10+9) MapMid/14 9.12ns ±14% 9.14ns ±13% ~ (p=0.927 n=10+10) MapMid/15 9.16ns ±12% 9.15ns ±16% ~ (p=0.955 n=10+10) MapMid/16 9.37ns ±11% 9.60ns ±23% ~ (p=0.825 n=9+10) MapLast/1 4.08ns ± 1% 3.92ns ± 0% -3.91% (p=0.000 n=10+9) MapLast/2 4.37ns ± 1% 4.28ns ± 1% -1.95% (p=0.000 n=10+10) MapLast/3 4.94ns ± 2% 4.65ns ± 1% -5.79% (p=0.000 n=9+8) MapLast/4 5.40ns ± 3% 5.02ns ± 2% -7.13% (p=0.000 n=9+9) MapLast/5 5.88ns ± 2% 5.67ns ± 2% -3.57% (p=0.000 n=10+10) MapLast/6 6.48ns ± 3% 5.90ns ± 2% -8.89% (p=0.000 n=10+10) MapLast/7 7.01ns ± 2% 6.27ns ± 5% -10.56% (p=0.000 n=10+10) MapLast/8 7.60ns ± 2% 6.62ns ± 2% -12.93% (p=0.000 n=9+10) MapLast/9 10.6ns ± 9% 10.9ns ±15% ~ (p=0.344 n=9+10) MapLast/10 11.0ns ±12% 10.9ns ±14% ~ (p=0.985 n=10+10) MapLast/11 11.4ns ±12% 11.8ns ±22% ~ (p=0.671 n=10+10) MapLast/12 11.6ns ±10% 12.1ns ±19% ~ (p=0.617 n=10+10) MapLast/13 12.5ns ±23% 11.8ns ±13% ~ (p=0.827 n=10+9) MapLast/14 10.5ns ±22% 10.4ns ± 5% ~ (p=0.797 n=10+9) MapLast/15 10.0ns ±15% 10.3ns ±16% ~ (p=0.565 n=10+10) MapLast/16 10.4ns ±12% 10.5ns ±13% ~ (p=0.889 n=10+9) MapCycle 22.3ns ± 1% 22.0ns ± 2% -1.43% (p=0.002 n=9+10) RepeatedLookupStrMapKey32 16.4ns ± 1% 16.6ns ± 1% +1.24% (p=0.000 n=10+9) RepeatedLookupStrMapKey1M 35.6µs ± 0% 35.4µs ± 1% -0.62% (p=0.002 n=10+10) NewEmptyMap 5.36ns ± 1% 9.05ns ± 1% +69.02% (p=0.000 n=10+8) NewSmallMap 51.2ns ± 2% 33.7ns ± 1% -34.22% (p=0.000 n=10+9) MapIter 83.8ns ± 1% 88.4ns ± 1% +5.55% (p=0.000 n=10+10) MapIterEmpty 4.32ns ± 3% 5.54ns ± 3% +28.12% (p=0.000 n=10+10) SameLengthMap 4.31ns ± 1% 4.59ns ± 2% +6.41% (p=0.000 n=9+10) BigKeyMap 24.2ns ± 2% 24.3ns ± 1% ~ (p=0.432 n=10+10) BigValMap 24.3ns ± 1% 24.4ns ± 2% ~ (p=0.200 n=10+9) SmallKeyMap 17.5ns ± 1% 18.5ns ± 2% +5.81% (p=0.000 n=9+10) MapPopulate/1 29.0ns ± 4% 18.8ns ± 1% -35.27% (p=0.000 n=10+9) MapPopulate/10 736ns ± 5% 693ns ± 4% -5.92% (p=0.000 n=10+10) MapPopulate/100 11.3µs ± 2% 10.8µs ± 3% -4.38% (p=0.000 n=10+10) MapPopulate/1000 139µs ± 8% 132µs ± 4% -5.10% (p=0.002 n=10+10) MapPopulate/10000 1.21ms ± 5% 1.16ms ± 5% -4.56% (p=0.002 n=10+10) MapPopulate/100000 12.2ms ± 3% 11.8ms ± 5% ~ (p=0.052 n=10+10) ComplexAlgMap 73.9ns ± 1% 74.4ns ± 2% ~ (p=0.161 n=9+10) GoMapClear/Reflexive/1 36.0ns ± 1% 26.9ns ± 2% -25.31% (p=0.000 n=10+10) GoMapClear/Reflexive/10 35.2ns ± 1% 24.4ns ± 1% -30.62% (p=0.000 n=10+10) GoMapClear/Reflexive/100 69.6ns ± 2% 59.2ns ± 1% -14.92% (p=0.000 n=10+10) GoMapClear/Reflexive/1000 1.06µs ± 2% 1.05µs ± 1% -1.16% (p=0.013 n=10+9) GoMapClear/Reflexive/10000 11.7µs ± 1% 11.7µs ± 1% ~ (p=0.542 n=10+10) GoMapClear/NonReflexive/1 96.3ns ± 1% 90.0ns ± 1% -6.52% (p=0.000 n=10+10) GoMapClear/NonReflexive/10 110ns ± 2% 101ns ± 0% -8.10% (p=0.000 n=10+7) GoMapClear/NonReflexive/100 270ns ± 2% 235ns ± 2% -12.94% (p=0.000 n=10+10) GoMapClear/NonReflexive/1000 3.02µs ± 2% 2.48µs ± 1% -17.92% (p=0.000 n=10+10) GoMapClear/NonReflexive/10000 23.7µs ± 1% 19.6µs ± 1% -17.30% (p=0.000 n=10+9) MapPop100 9.65µs ± 6% 9.18µs ± 8% -4.82% (p=0.008 n=9+10) MapPop1000 162µs ± 6% 148µs ± 4% -8.67% (p=0.000 n=9+9) MapPop10000 3.05ms ± 8% 2.82ms ±15% -7.66% (p=0.023 n=10+10) MapAssign/Int32/256 15.7ns ± 4% 14.6ns ± 2% -7.08% (p=0.000 n=10+10) MapAssign/Int32/65536 29.8ns ± 1% 30.4ns ± 0% +2.04% (p=0.000 n=10+8) MapAssign/Int64/256 14.9ns ± 5% 14.8ns ± 4% ~ (p=0.611 n=10+10) MapAssign/Int64/65536 30.3ns ± 2% 30.4ns ± 1% +0.54% (p=0.046 n=10+9) MapAssign/Str/256 17.8ns ± 3% 19.8ns ± 4% +11.08% (p=0.000 n=10+10) MapAssign/Str/65536 35.7ns ± 1% 36.4ns ± 1% +1.82% (p=0.000 n=10+10) MapOperatorAssign/Int32/256 18.8ns ± 5% 14.6ns ± 3% -22.57% (p=0.000 n=10+10) MapOperatorAssign/Int32/65536 29.8ns ± 1% 30.5ns ± 1% +2.39% (p=0.000 n=10+10) MapOperatorAssign/Int64/256 16.6ns ± 4% 15.0ns ± 6% -9.34% (p=0.000 n=10+10) MapOperatorAssign/Int64/65536 30.1ns ± 1% 31.7ns ± 2% +5.21% (p=0.000 n=10+10) MapOperatorAssign/Str/256 1.70µs ± 1% 1.61µs ± 2% -5.55% (p=0.000 n=10+8) MapOperatorAssign/Str/65536 289ns ± 7% 294ns ± 4% ~ (p=0.425 n=10+10) MapAppendAssign/Int32/256 34.3ns ± 2% 31.0ns ± 3% -9.59% (p=0.000 n=9+9) MapAppendAssign/Int32/65536 51.8ns ± 3% 47.1ns ±13% -9.17% (p=0.002 n=9+10) MapAppendAssign/Int64/256 32.5ns ± 8% 31.2ns ± 6% ~ (p=0.065 n=10+10) MapAppendAssign/Int64/65536 51.4ns ± 4% 47.2ns ±10% -8.07% (p=0.005 n=9+10) MapAppendAssign/Str/256 105ns ±12% 109ns ± 4% ~ (p=0.138 n=10+8) MapAppendAssign/Str/65536 101ns ±14% 81ns ± 8% -19.82% (p=0.000 n=10+9) MapDelete/Int32/100 32.0ns ± 1% 35.0ns ± 2% +9.59% (p=0.000 n=9+10) MapDelete/Int32/1000 27.0ns ± 3% 30.3ns ± 1% +12.10% (p=0.000 n=10+9) MapDelete/Int32/10000 29.2ns ± 1% 32.9ns ± 2% +12.80% (p=0.000 n=10+10) MapDelete/Int64/100 31.5ns ± 1% 35.7ns ± 2% +13.16% (p=0.000 n=10+10) MapDelete/Int64/1000 27.0ns ± 2% 30.6ns ± 1% +13.21% (p=0.000 n=10+10) MapDelete/Int64/10000 30.3ns ± 1% 34.4ns ± 3% +13.47% (p=0.000 n=10+10) MapDelete/Str/100 23.4ns ± 8% 26.7ns ± 6% +14.10% (p=0.000 n=10+9) MapDelete/Str/1000 31.0ns ± 2% 35.1ns ± 3% +13.19% (p=0.000 n=10+9) MapDelete/Str/10000 38.8ns ± 1% 43.4ns ± 2% +12.02% (p=0.000 n=9+10) Change-Id: I564ce0f40936589f0f9b837f7f2bbcca4c4a1070 Reviewed-on: https://go-review.googlesource.com/c/142437 Reviewed-by: Giovanni Bajo <rasky@develer.com> Reviewed-by: Martin Möhrmann <martisch@uos.de> Run-TryBot: Martin Möhrmann <martisch@uos.de> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-23runtime: use multiplication with overflow check for makemapMartin Möhrmann
This improves performance for maps with a bucket size (key+value*8 bytes) larger than 32 bytes and removes loading a value from the maxElems array for smaller bucket sizes. name old time/op new time/op delta MakeMap/[Byte]Byte 93.5ns ± 1% 91.8ns ± 1% -1.83% (p=0.000 n=10+10) MakeMap/[Int]Int 134ns ± 1% 127ns ± 2% -5.61% (p=0.000 n=9+10) Updates #21588 Change-Id: I53f77186769c4bd0f2b90f3c6c17df643b060e39 Reviewed-on: https://go-review.googlesource.com/c/143797 Run-TryBot: Martin Möhrmann <martisch@uos.de> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-08-22runtime: catch concurrent stacks more oftenZachary Amsden
If two goroutines are racing on a map, one of them will exit cleanly, clearing the hashWriting bit, and the other will likely notice and panic. If we use XOR instead of OR to set the bit in the first place, even numbers of racers will hopefully all see the bit cleared and panic simultaneously, giving the full set of available stacks. If a third racer sneaks in, we are no worse than the current code, and the generated code should be no more expensive. In practice, this catches most racing goroutines even in very tight races. See the demonstration program posted on https://github.com/golang/go/issues/26703 for an example. Fixes #26703 Change-Id: Idad17841a3127c24bd0a659b754734f70e307434 Reviewed-on: https://go-review.googlesource.com/126936 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2018-08-22reflect: add Value.MapRange method and MapIter typeAlan Donovan
Example of use: iter := reflect.ValueOf(m).MapRange() for iter.Next() { k := iter.Key() v := iter.Value() ... } See issue golang/go#11104 Q. Are there any benchmarks that would exercise the new calls to copyval in existing code? Change-Id: Ic469fcab5f1d9d853e76225f89bde01ee1d36e7a Reviewed-on: https://go-review.googlesource.com/33572 Reviewed-by: Keith Randall <khr@golang.org>
2018-07-02runtime: fix typo in mapextra commentcch123
Change-Id: Idbd8a1b5bfeb1c23c86cef0697cf0380900e95f3 GitHub-Last-Rev: a8c2b27046582c4eef932a8502826a3b23b8dab3 GitHub-Pull-Request: golang/go#26175 Reviewed-on: https://go-review.googlesource.com/121821 Reviewed-by: Keith Randall <khr@golang.org>
2018-06-26cmd/compile: map delete should clear value alwaysVladimir Kuzmin
Map delete must clear value every time because newly added map optimizations of compound-assignment operators (CL #91557) rely on this behavior of map delete. It slows down map delete operation for non-reference types: name old time/op new time/op delta MapDelete/Int32/100 23.9ns ± 2% 27.8ns ± 4% +16.04% (p=0.000 n=20+20) MapDelete/Int32/1000 21.5ns ± 2% 25.2ns ± 2% +17.06% (p=0.000 n=20+19) MapDelete/Int32/10000 24.2ns ± 6% 27.2ns ± 5% +12.39% (p=0.000 n=19+19) MapDelete/Int64/100 24.2ns ± 4% 27.7ns ± 2% +14.55% (p=0.000 n=20+20) MapDelete/Int64/1000 22.1ns ± 2% 24.8ns ± 2% +12.36% (p=0.000 n=10+20) Fixes #25936 Change-Id: I8499b790cb5bb019938161b3e50f3243d9bbb79c Reviewed-on: https://go-review.googlesource.com/120255 Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
2018-05-08cmd/compile: optimize map-clearing range idiomMartin Möhrmann
replace map clears of the form: for k := range m { delete(m, k) } (where m is map with key type that is reflexive for ==) with a new runtime function that clears the maps backing array with a memclr and reinitializes the hmap struct. Map key types that for example contain floats are not replaced by this optimization since NaN keys cannot be deleted from maps using delete. name old time/op new time/op delta GoMapClear/Reflexive/1 92.2ns ± 1% 47.1ns ± 2% -48.89% (p=0.000 n=9+9) GoMapClear/Reflexive/10 108ns ± 1% 48ns ± 2% -55.68% (p=0.000 n=10+10) GoMapClear/Reflexive/100 303ns ± 2% 110ns ± 3% -63.56% (p=0.000 n=10+10) GoMapClear/Reflexive/1000 3.58µs ± 3% 1.23µs ± 2% -65.49% (p=0.000 n=9+10) GoMapClear/Reflexive/10000 28.2µs ± 3% 10.3µs ± 2% -63.55% (p=0.000 n=9+10) GoMapClear/NonReflexive/1 121ns ± 2% 124ns ± 7% ~ (p=0.097 n=10+10) GoMapClear/NonReflexive/10 137ns ± 2% 139ns ± 3% +1.53% (p=0.033 n=10+10) GoMapClear/NonReflexive/100 331ns ± 3% 334ns ± 2% ~ (p=0.342 n=10+10) GoMapClear/NonReflexive/1000 3.64µs ± 3% 3.64µs ± 2% ~ (p=0.887 n=9+10) GoMapClear/NonReflexive/10000 28.1µs ± 2% 28.4µs ± 3% ~ (p=0.247 n=10+10) Fixes #20138 Change-Id: I181332a8ef434a4f0d89659f492d8711db3f3213 Reviewed-on: https://go-review.googlesource.com/110055 Reviewed-by: Keith Randall <khr@golang.org>
2018-05-06runtime: remove hmap field from maptypesMartin Möhrmann
The hmap field in the maptype is only used by the runtime to check the sizes of the hmap structure created by the compiler and runtime agree. Comments are already present about the hmap structure definitions in the compiler and runtime needing to be in sync. Add a test that checks the runtimes hmap size is as expected to detect when the compilers and runtimes hmap sizes diverge instead of checking this at runtime when a map is created. Change-Id: I974945ebfdb66883a896386a17bbcae62a18cf2a Reviewed-on: https://go-review.googlesource.com/91796 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2018-04-30runtime,cmd/compile: adjust and correct path names in comments of map codeMartin Möhrmann
Some of the comments relative paths do not exist and reflect does not define its own hmap structure. Correct paths and consistently reference paths starting from the go src directory. Change-Id: I5204a3a98f77d65f17dcde98b847378cea05ad8a Reviewed-on: https://go-review.googlesource.com/94758 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2018-02-17runtime: rename map implementation and test files to use a common prefixMartin Möhrmann
Rename all map implementation and test files to use "map" as a file name prefix instead of "hashmap" for the implementation and "map" for the test file names. Change-Id: I7b317c1f7a660b95c6d1f1a185866f2839e69446 Reviewed-on: https://go-review.googlesource.com/90336 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>