go 并发安全map新宠:xsync

2024-06-12 09:39:43 浏览数 (2)

在go中,官方实现了并发安全的sync.Map。它的出现有一定争议(性能勉强),但因为并发安全,在go中仍然广泛使用。

今天介绍的xsync系列( &quot;github.com/puzpuzpuz/xsync/v3&quot;),使用了新的算法,对原官方的实现有一定的性能提升,此外,<mark style="background: #ff6666">它提供了Size方法</mark>,补充了官方sync.Map的一大短板。

此外,它还提供了CounterMPMCQueue(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 	&quot;github.com/puzpuzpuz/xsync/v3&quot;

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 &lt; 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 &gt; 1000000 {
                key = 0
            }
        }
    })
}

func BenchmarkXsyncLoad(b *testing.B) {
    m := xsync.NewMapOf[int, int]()
    for i := 0; i &lt; 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 &gt; 1000000 {
                key = 0
            }
        }
    })
}

Delete:删除

代码语言:javascript复制
func BenchmarkGosyncDelete(b *testing.B) {
    m := sync.Map{}
    for i := 0; i &lt; 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 &gt; 1000000 {
                key = 0
            }
        }
    })
}

func BenchmarkXsyncDelete(b *testing.B) {
    m := xsync.NewMapOf[int, int]()
    for i := 0; i &lt; 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 &gt; 1000000 {
                key = 0
            }
        }
    })
}

Size:元素数

代码语言:javascript复制
func BenchmarkXmapSize(b *testing.B) {
    m := xsync.NewMapOf[int, int]()
    for i := 0; i &lt; 1000000; i   {
        m.Store(i, i)
    }

    b.ResetTimer()
    b.RunParallel(func(pb *testing.PB) {
        for pb.Next() {
            m.Size()
        }
    })
}

0 人点赞