當我比較和go 的效率時sync.mu,預計效率低于后兩者。但是當我做一個基準測驗時,發現執行持續時間更少,使用. 所以我想知道原因,或者也許有一個最佳實踐。sync.Mapatomic.Valuesync.musync.mu
代碼
原始碼在這里https://go.dev/play/p/WODF8Tyyw4d簡化如下:
- 場景1:改變地圖中的隨機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)
- 場景2:改變整個地圖,
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
uj5u.com熱心網友回復:
你沒有比較這種同步結構的效率,因為你也是做 I/0 的。這段代碼中還有 goroutines 和 waitgroups……不知道我是否理解
您應該考慮在相同的背景關系中比較類似的用法。
例如,增加一個計數器。您在 sync.Map、atomic.Value 中有一個計數器并受互斥鎖保護。
每種方法各有利弊,但互斥體只處理同步,而其他結構也處理存盤。
互斥體應該更快,因為它……不那么復雜。
但是,如果您處理比 uint64 更復雜的東西,也許 atomic.Value 的開銷可能沒問題。
例如,使用互斥鎖,您需要特定的鎖定/解鎖順序,并且您可能會在沒有適當測驗 競爭條件檢測器的情況下發現一些問題。
雖然 atomic.Value 會為您處理這個問題。
我從不使用 sync.Map,但我在生產中使用 atomic.Value 有非常高效的代碼——我對此很滿意。
正確的基準測驗需要更技術性的方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/450149.html
