在go中,官方实现了并发安全的sync.Map
。它的出现有一定争议(性能勉强),但因为并发安全,在go中仍然广泛使用。
今天介绍的xsync
系列( "github.com/puzpuzpuz/xsync/v3"
),使用了新的算法,对原官方的实现有一定的性能提升,此外,<mark style="background: #ff6666">它提供了Size
方法</mark>,补充了官方sync.Map
的一大短板。
此外,它还提供了Counter
,MPMCQueue(bounded multi-producer multi-consumer concurrent queue)
,RBMutex
等多种并发安全结构。功能十分强大。
Map性能测试
机器
cpu: Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz
结论
go官方 | xsync map | |
---|---|---|
写入(store) | 617.0 ns/op 65 B/op 5 allocs/op | 70.51 ns/op 44 B/op 3 allocs/op |
读取(load) | 20.67 ns/op 0 B/op 0 allocs/op | 5.596 ns/op 0 B/op 0 allocs/op (100万kv) |
删除(delete) | 20.34 ns/op 0 B/op 0 allocs/op | 28.16 ns/op 0 B/op 0 allocs/op (100万kv) |
元素数(size) | 不支持 | 3.888 ns/op 0 B/op 0 allocs/op (100万kv) |
xsync.Map
有极大优势,尤其是在Store
场景下,是替换系统sync.Map
的优质选项。
附录
Store:写入
代码语言:javascript复制// import "github.com/puzpuzpuz/xsync/v3"
func BenchmarkGosyncStore(b *testing.B) {
m := sync.Map{}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
m.Store(fmt.Sprint(i), i)
i = 1
}
})
}
func BenchmarkXsyncStore(b *testing.B) {
m := xsync.NewMapOf[string, int]()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
m.Store(fmt.Sprint(i), i)
i = 1
}
})
}
Load:读取
代码语言:javascript复制func BenchmarkGosyncLoad(b *testing.B) {
m := sync.Map{}
for i := 0; i < 1000000; i {
m.Store(i, i)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
key := 0
for pb.Next() {
m.Load(key)
key = 1
if key > 1000000 {
key = 0
}
}
})
}
func BenchmarkXsyncLoad(b *testing.B) {
m := xsync.NewMapOf[int, int]()
for i := 0; i < 1000000; i {
m.Store(i, i)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
key := 0
for pb.Next() {
m.Load(key)
key = 1
if key > 1000000 {
key = 0
}
}
})
}
Delete:删除
代码语言:javascript复制func BenchmarkGosyncDelete(b *testing.B) {
m := sync.Map{}
for i := 0; i < 1000000; i {
m.Store(i, i)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
key := 0
for pb.Next() {
m.Delete(key)
key = 1
if key > 1000000 {
key = 0
}
}
})
}
func BenchmarkXsyncDelete(b *testing.B) {
m := xsync.NewMapOf[int, int]()
for i := 0; i < 1000000; i {
m.Store(i, i)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
key := 0
for pb.Next() {
m.Delete(key)
key = 1
if key > 1000000 {
key = 0
}
}
})
}
Size:元素数
代码语言:javascript复制func BenchmarkXmapSize(b *testing.B) {
m := xsync.NewMapOf[int, int]()
for i := 0; i < 1000000; i {
m.Store(i, i)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Size()
}
})
}