diff options
| author | Michael Anthony Knyszek <mknyszek@google.com> | 2024-08-26 14:18:26 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-11-18 20:35:42 +0000 |
| commit | aecb8faa91e2b40e3651ee93c8e70635ed367677 (patch) | |
| tree | 2cdaf8a697386367cc4874ef74b6627af6913258 /src/internal | |
| parent | 06e6b8efa4c9fbe4b8ceec8c655011117a50279a (diff) | |
| download | go-aecb8faa91e2b40e3651ee93c8e70635ed367677.tar.xz | |
sync: make HashTrieMap[any, any] the default implementation of Map
This change adds a GOEXPERIMENT, synchashtriemap, which replaces the
internals of a sync.Map with internal/sync.HashTrieMap[any, any]. The
main purpose behind this change is improved performance. Across almost
every benchmark, HashTrieMap[any, any] performs better than Map.
Also, relax TestMapClearNoAllocations to allow for one allocation.
Currently, the HashTrieMap allocates a new empty root node and stores
it: that's the whole clear operation. At the cost of some complexity, we
could allow Clear to have zero allocations by clearing the root node.
The complexity comes down to allowing threads to race to install a new
root node *or* creating a top-level mutex for installing a root node.
But I'm not sure this is worth it. Whether Clear or some other operation
takes the hit for allocating a single node almost certainly doesn't
matter. And Clear is still much, much faster in the new implementation
than the old, so I don't consider this a regression.
Change-Id: I939aa70a0edf2e850cedbea239aaf29a11a77b79
Reviewed-on: https://go-review.googlesource.com/c/go/+/608335
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/internal')
| -rw-r--r-- | src/internal/buildcfg/exp.go | 1 | ||||
| -rw-r--r-- | src/internal/goexperiment/exp_synchashtriemap_off.go | 8 | ||||
| -rw-r--r-- | src/internal/goexperiment/exp_synchashtriemap_on.go | 8 | ||||
| -rw-r--r-- | src/internal/goexperiment/flags.go | 3 |
4 files changed, 20 insertions, 0 deletions
diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go index c8ff974767..332c9afa57 100644 --- a/src/internal/buildcfg/exp.go +++ b/src/internal/buildcfg/exp.go @@ -80,6 +80,7 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { AliasTypeParams: true, SwissMap: true, SpinbitMutex: haveXchg8, + SyncHashTrieMap: true, } // Start with the statically enabled set of experiments. diff --git a/src/internal/goexperiment/exp_synchashtriemap_off.go b/src/internal/goexperiment/exp_synchashtriemap_off.go new file mode 100644 index 0000000000..cab23aac1d --- /dev/null +++ b/src/internal/goexperiment/exp_synchashtriemap_off.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build !goexperiment.synchashtriemap + +package goexperiment + +const SyncHashTrieMap = false +const SyncHashTrieMapInt = 0 diff --git a/src/internal/goexperiment/exp_synchashtriemap_on.go b/src/internal/goexperiment/exp_synchashtriemap_on.go new file mode 100644 index 0000000000..87433ef4de --- /dev/null +++ b/src/internal/goexperiment/exp_synchashtriemap_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.synchashtriemap + +package goexperiment + +const SyncHashTrieMap = true +const SyncHashTrieMapInt = 1 diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go index f3c9c17d32..e654471a6a 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -122,4 +122,7 @@ type Flags struct { // SpinbitMutex enables the new "spinbit" mutex implementation on supported // platforms. See https://go.dev/issue/68578. SpinbitMutex bool + + // SyncHashTrieMap enables the HashTrieMap sync.Map implementation. + SyncHashTrieMap bool } |
