首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从字符串池中驱逐未使用的记录的最佳方法是什么?

从字符串池中驱逐未使用的记录的最佳方法是什么?
EN

Stack Overflow用户
提问于 2021-07-19 12:05:09
回答 1查看 48关注 0票数 1

我在Golang中实现了一个缓存。假设缓存可以实现为sync.Map,并使用整型键和值作为结构:

代码语言:javascript
复制
type value struct {
    fileName     string
    functionName string
}

大量的记录具有相同的fileNamefunctionName。为了节省内存,我想使用字符串池。Go有不变的字符串,我的想法是这样的:

代码语言:javascript
复制
var (
    cache      sync.Map
    stringPool sync.Map
)

type value struct {
    fileName     string
    functionName string
}

func addRecord(key int64, val value) {
    fileName, _ := stringPool.LoadOrStore(val.fileName, val.fileName)
    val.fileName = fileName.(string)
    functionName, _ := stringPool.LoadOrStore(val.functionName, val.functionName)
    val.functionName = functionName.(string)
    cache.Store(key, val)
}

我的想法是将每个唯一的字符串(fileNamefunctionName)保存在内存中一次。它会起作用吗?

缓存实现必须是并发安全的。缓存中的记录数约为10^8。字符串池中的记录数约为10^6。

我有一些逻辑可以从缓存中删除记录。主缓存大小没有问题。

您能建议一下如何管理字符串池大小吗?

我正在考虑为字符串池中的每条记录存储引用计数。它需要额外的同步或可能的全局锁来维护它。我希望实现尽可能简单。您可以在我的代码片段中看到,我没有使用额外的互斥锁。

或者我可能需要遵循完全不同的方法来最小化缓存的内存使用?

EN

回答 1

Stack Overflow用户

发布于 2021-07-19 13:52:50

您尝试使用stringPool执行的操作通常称为string interning。有像github.com/josharian/intern这样的库为这类问题提供了“足够好”的解决方案,并且不需要您手动维护stringPool映射。请注意,没有任何解决方案(包括您的解决方案,假设您最终从stringPool中删除了一些元素)可以可靠地对字符串进行100%的重复数据删除,而不会导致不切实际的CPU开销。

顺便说一句,值得指出的是,sync.Map就是not really designed for update-heavy workloads。根据所使用的key,在调用cache.Store时可能会遇到严重的争用。此外,由于sync.Map的键和值都依赖于interface{},因此它通常比普通的map产生更多的分配。确保对实际工作负载进行基准测试,以确保您选择了正确的方法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68434993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档