为了账号安全,请及时绑定邮箱和手机立即绑定

`sync.Mutex`、`sync.Map` 和 `atomic.Value` 的效率比较

`sync.Mutex`、`sync.Map` 和 `atomic.Value` 的效率比较

Go
回首忆惘然 2022-11-23 20:25:41

当我比较sync.mu,sync.Map和atomic.Valuego 的效率时,预计它sync.mu的效率低于后两者。但是当我做一个基准测试时,发现使用sync.mu. 所以我想知道原因或者可能有最佳实践。


代码


源代码在这里https://go.dev/play/p/WODF8Tyyw4d简化如下:


Scene1:在map中改变一个随机的kv对,sync.muvssync.Map

// sync.mu reader

mu.Lock()

tmp := tA[idx]

mu.Unlock()

// sync.mu writer

mu.Lock()

tA[idx] = data

mu.Unlock()


// sync.Map reader

v, _ := tB.Load(idx)

// sync.Map writer

tB.Store(idx, data)

Scene2:换一整张图,sync.muvsatomic.Value

// sync.mu reader

mu.Lock()

tmp := tA[0]

mu.Unlock()

// sync.mu Writer

mu.Lock()

tA = data

mu.Unlock()


// atomic.Value reader

v := tC.Load().(map[int]int)[0]

// atomic.Value writer

tC.Store(data)

结果


goos: darwin

goarch: amd64

pkg: sync-demo

cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz

BenchmarkMu-12          1000000000               0.5401 ns/op

BenchmarkSyncMap-12     1000000000               0.5504 ns/op

BenchmarkMuTotal-12     1000000000               0.5418 ns/op

BenchmarkAtomic-12      1000000000               0.5457 ns/op

PASS

ok      sync-demo    64.195s


查看完整描述

1 回答

?
慕盖茨4494581

TA贡献1574条经验 获得超11个赞

你没有比较这种同步结构的效率,因为你也在做 I/0。这段代码中还有 goroutines 和 waitgroups ……不确定我是否理解

您应该考虑比较相同上下文中的相似用法。

例如,增加一个计数器。您在 sync.Map 中有一个计数器,atomic.Value 并受互斥锁保护。

每种方法都各有利弊,但互斥体只处理同步,而其他结构也处理存储。

Mutex 应该更快,因为它……不那么复杂。

但是,如果您处理比 uint64 更复杂的东西,则 atomic.Value 的开销可能没问题。

例如,使用互斥锁你需要一个特定的锁定/解锁顺序,你可能会在没有适当的测试+竞争条件检测器的情况下发现一些问题。

而 atomic.Value 会为你处理这个。

我从不使用 sync.Map 但我在使用 atomic.Value 的生产中有非常高效的代码 - 我对此没有意见。

正确的基准需要更多的技术方法。


查看完整回答
反对 回复 2022-11-23

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信