Go Loador在sync.Map中存储,每次都不创建新结构
是否可以在每次不创建新结构的情况下将装载机存储到Go中?如果没有,有哪些替代方案 这里的用例是,如果我使用Go Loador在sync.Map中存储,每次都不创建新结构,go,concurrency,Go,Concurrency,是否可以在每次不创建新结构的情况下将装载机存储到Go中?如果没有,有哪些替代方案 这里的用例是,如果我使用sync.Map作为缓存,其中缓存未命中很少(但可能),并且对于要添加到映射中的缓存未命中,我需要在每次调用LoadOrStore时初始化结构,而不是在需要时创建结构。我担心这会伤害GC,初始化数十万个不需要的结构 在Java中,可以使用 Map类似于Go-Map[interface{}]interface{},但对于 由多个goroutine并发使用,无需额外锁定或 协调。加载、存储和
sync.Map
作为缓存,其中缓存未命中很少(但可能),并且对于要添加到映射中的缓存未命中,我需要在每次调用LoadOrStore
时初始化结构,而不是在需要时创建结构。我担心这会伤害GC,初始化数十万个不需要的结构
在Java中,可以使用
Map类似于Go-Map[interface{}]interface{},但对于
由多个goroutine并发使用,无需额外锁定或
协调。加载、存储和删除以摊销常量运行
时间
地图类型是专用的。大多数代码应该使用普通的Go映射
相反,使用单独的锁定或协调,以实现更好的类型安全性
并且更容易在地图上维护其他不变量
内容
映射类型针对两种常见用例进行了优化:(1)当
因为一个给定的密钥只写了一次,但读了很多次,如
仅增长的缓存,或(2)当多个goroutine读取、写入、,
并覆盖不相交的键集的条目。在这两种情况下,,
与Go相比,使用Map可以显著减少锁争用
映射与单独的互斥体或RWMutex配对
解决这些问题的通常方法是构造一个使用模型,然后对其进行基准测试 例如,由于“缓存未命中非常罕见”,因此假设
Load
在大多数时间都可以工作,并且只有LoadOrStore
(具有值分配和初始化)在必要时才能工作
$ go test map_test.go -bench=. -benchmem
BenchmarkHit-4 2 898810447 ns/op 44536 B/op 1198 allocs/op
BenchmarkMiss-4 1 2958103053 ns/op 483957168 B/op 43713042 allocs/op
$
map\u test.go
:
package main
import (
"strconv"
"sync"
"testing"
)
func BenchmarkHit(b *testing.B) {
for N := 0; N < b.N; N++ {
var m sync.Map
for i := 0; i < 64*1024; i++ {
for k := 0; k < 256; k++ {
// Assume cache hit
v, ok := m.Load(k)
if !ok {
// allocate and initialize value
v = strconv.Itoa(k)
a, loaded := m.LoadOrStore(k, v)
if loaded {
v = a
}
}
_ = v
}
}
}
}
func BenchmarkMiss(b *testing.B) {
for N := 0; N < b.N; N++ {
var m sync.Map
for i := 0; i < 64*1024; i++ {
for k := 0; k < 256; k++ {
// Assume cache miss
// allocate and initialize value
var v interface{} = strconv.Itoa(k)
a, loaded := m.LoadOrStore(k, v)
if loaded {
v = a
}
_ = v
}
}
}
}
主程序包
进口(
“strconv”
“同步”
“测试”
)
func BenchmarkHit(b*testing.b){
对于N:=0;N
您可以尝试:
var m sync.Map
s, ok := m.Load("key")
if !ok {
s, _ = m.LoadOrStore("key", "value")
}
fmt.Println(s)
然而,这一可能的重复并不能回答这个问题。如何在Go中计算FabSent?具体地说,只有在映射中缺少新值时才创建新值?这个示例首先破坏了使用sync.map的意义
var m sync.Map
s, ok := m.Load("key")
if !ok {
s, _ = m.LoadOrStore("key", "value")
}
fmt.Println(s)