按值或引用存储 net.Conn?

我的应用程序使用 async.Map来存储通过多个 goroutine 同时访问的打开的套接字连接。

我想知道是将这些连接存储为结构net.Conn还是引用*net.Conn

这两种选择的优点/缺点是什么?首选的解决方案是什么?


眼眸繁星
浏览 75回答 1
1回答

侃侃尔雅

虽然@blackgreen 是正确的,但我会稍微扩展一下推理。该sync.Map类型被明确定义为在 上进行操作interface{}。现在请记住,在 Go 中,接口不仅仅是类型系统使用的抽象;相反,您可以拥有接口类型的值,并且这些值的内存表示是struct包含两个指针——指向描述存储在变量中的值的动态类型的内部对象,以及指向值本身(或副本它由运行时在堆上创建)。这意味着,如果您要在 中存储指向任何内容的指针,则存储的sync.Map任何此类指针都将被转换为类型的值,interface{}并且它将在 中占据完全相同的空间sync.Map。相反,如果您将类型的值net.Conn直接存储在那里,它们将被直接存储——仅仅是因为它们已经是接口值,所以 Go 只会复制这对指针。从表面上看,这两种方法在使用的空间方面都差不多,但请容忍我。要存储指向容器数据类型(net.Conn例如sync.Map编译器安排确保原始net.Conn值直接在堆上分配。换句话说,存储指向接口类型变量的指针可能(并且通常会——由于典型代码的组织方式)在内存使用方面更加浪费。此外,大多数取消引用(指针追逐)往往会破坏 CPU 缓存;这不会改变游戏规则,但当您在紧密循环中迭代集合时可能会增加几微秒。话虽如此,我建议不要完全放弃在容器中存储指针,例如sync.Map:偶尔它会派上用场——例如,为了将数组重用于切片,您通常存储指向此类数组的第一个元素的指针。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go