首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按值或引用存储net.Conn?

按值或引用存储net.Conn?
EN

Stack Overflow用户
提问于 2022-01-18 11:01:41
回答 1查看 373关注 0票数 1

我的应用程序使用sync.Map来存储打开的套接字连接,这些连接可以通过多个goroutines并发访问。

我想知道是将这些连接存储为structs net.Conn还是作为references *net.Conn存储。

这两种选择的好处/缺点是什么,优先的解决方案是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-18 12:22:30

虽然@blackgreen是正确的,但我会对推理做一些扩展。

sync.Map类型被显式定义为在interface{}上操作。

现在请记住,在Go中,接口不仅仅是类型系统使用的抽象;相反,您可以拥有接口类型的值,而这些值的内存中表示形式是包含两个指针的struct --用于描述存储在变量中的值的动态类型的内部对象,以及值本身(或运行时在堆上创建的值的副本)。

这意味着,如果要在sync.Map中存储指向任何内容的指针,则存储的任何此类指针都将转换为interface{}类型的值,并且在sync.Map中占据完全相同的空间。

如果您将net.Conn类型的值直接存储在那里,那么它们将直接存储--仅仅因为它们已经是接口值,所以Go将只复制这对指针。

从表面上看,这两种方法在所使用的空间上都是相同的,但我不同意。

若要将指向net.Conn值的指针存储在容器数据类型(如sync.Map )中,程序必须确保在堆上分配该值(而不是直接在当前运行的sync.Map的堆栈上分配该值),这一事实可能迫使编译器安排确保直接在堆上分配原始net.Conn值。

换句话说,存储指向接口类型变量的指针在内存使用方面可能会(而且通常也会--由于典型代码的组织方式)更加浪费。

此外,大多数反引用(指针追逐)倾向于破坏CPU缓存;这不是一个游戏改变器,但当您在紧循环中遍历集合时,可能会增加几个参数。

话虽如此,我还是建议您不要直接在像sync.Map这样的容器中丢弃存储指针:有时候它会派上用场--例如,为了将数组重用到片中,您通常会存储指向此类数组的第一个元素的指针。

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

https://stackoverflow.com/questions/70754495

复制
相关文章

相似问题

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