go 并发安全map新宠:xsync 在go中,官方实现了并发安全的`sync.Map`。它的出现有一定争议(性能勉强),但因为并发安全,在go中仍然广泛使用。 今天介绍的`xsync`系列(` "github.com/puzpuzpuz/xsync/v3"`),使用了[新的算法](https://github.com/puzpuzpuz/xsync?tab=readme-ov-file#map),对原官方的实现有一定的性能提升,此外,它提供了`Size`方法,补充了官方`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:写入 ``` // 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:读取 ``` 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:删除 ``` 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:元素数 ``` 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() } }) } ``` 来自 大脸猪 写于 2024-06-11 13:47 -- 更新于2024-09-14 01:18 -- 0 条评论