genericsyncmap
July 25, 2026 ยท View on GitHub
genericsyncmap is a type-safe generic wrapper for Go's sync.Map. It provides the full Go 1.24 sync.Map API without caller-side type assertions, plus typed iteration and collection helpers.
Features
- Type-safe keys and values
- Safe concurrent access without external locking
- Full method parity with Go 1.24's
sync.Map All,Keys,Values, andLenhelpers- Zero dependencies outside the standard library
Installation
go get github.com/donomii/genericsyncmap
Go 1.24 or newer is required.
Use
The zero value of Map is ready for use:
package main
import (
"fmt"
"github.com/donomii/genericsyncmap"
)
func main() {
var m syncmap.Map[string, int]
m.Store("apple", 10)
m.Store("banana", 20)
if val, ok := m.Load("apple"); ok {
fmt.Printf("apple: %d\n", val)
}
m.Delete("banana")
m.Clear()
}
SyncMap[K, V] remains an alias for Map[K, V], and NewSyncMap[K, V]() remains available for compatibility. Like sync.Map, a Map must not be copied after first use.
Atomic Operations
val, loaded := m.LoadOrStore("cherry", 5)
val, loaded = m.LoadAndDelete("apple")
prev, loaded := m.Swap("grape", 30)
swapped := m.CompareAndSwap("grape", 30, 35)
deleted := m.CompareAndDelete("grape", 35)
CompareAndSwap and CompareAndDelete require the old value to be comparable, matching sync.Map behavior. They panic if given a non-comparable old value.
Iteration
Use All with Go's range-over-function syntax:
for key, value := range m.All() {
fmt.Printf("%s: %d\n", key, value)
}
Range is also available. Returning false stops iteration:
m.Range(func(key string, value int) bool {
fmt.Printf("%s: %d\n", key, value)
return true
})
All and Range do not necessarily observe a consistent snapshot if the map is modified concurrently. Keys, Values, and Len inherit that behavior. Len iterates over the entire map in O(N) time.
Performance
The benchmarks compare genericsyncmap.Map, raw sync.Map, and a built-in map protected by sync.RWMutex. All mixed-workload maps are prepopulated with 1,024 keys, and operations and keys are selected independently.
Results from Go 1.26.2 on an Apple M5 Pro (darwin/arm64):
| Benchmark | genericsyncmap | sync.Map | map + RWMutex |
|---|---|---|---|
| Load hit | 5.18 ns/op | 4.68 ns/op | 3.78 ns/op |
| Store existing | 26.4 ns/op | 24.8 ns/op | 8.00 ns/op |
| Concurrent 50/50 load/store | 19.4 ns/op | 20.6 ns/op | 74.2 ns/op |
These results are a single-machine measurement, not a performance guarantee. Run the benchmarks for the workload and hardware that matter to you:
go test -bench . -benchmem
Like sync.Map, this package is optimized for workloads where entries are written once and read many times, or where goroutines access disjoint key sets.
License
MIT