我的應用程式使用 async.Map來存盤通過多個 goroutine 同時訪問的打開的套接字連接。
我想知道是將這些連接存盤為結構net.Conn還是參考*net.Conn。
這兩種選擇的優點/缺點是什么?首選的解決方案是什么?
uj5u.com熱心網友回復:
雖然@blackgreen 是正確的,但我會稍微擴展一下推理。
該sync.Map型別被明確定義為在 上進行操作interface{}。
現在請記住,在 Go 中,介面不僅僅是型別系統使用的抽象;相反,您可以擁有介面型別的值,并且這些值的記憶體表示是struct包含兩個指標——指向描述存盤在變數中的值的動態型別的內部物件,以及指向值本身(或副本它由運行時在堆上創建)。
這意味著,如果您要在 中存盤指向任何內容的指標,則存盤的sync.Map任何此類指標都將被轉換為型別的值,interface{}并且它將在 中占據完全相同的空間sync.Map。
相反,如果您將型別的值net.Conn直接存盤在那里,它們將被直接存盤——僅僅是因為它們已經是介面值,所以 Go 只會復制這對指標。
從表面上看,這兩種方法在使用的空間方面都差不多,但請容忍我。
要存盤指向容器資料型別(net.Conn例如sync.Map編譯器安排確保原始net.Conn值直接在堆上分配。
換句話說,存盤指向介面型別變數的指標可能(并且通常會——由于典型代碼的組織方式)在記憶體使用方面更加浪費。
此外,大多數取消參考(指標追逐)往往會破壞 CPU 快取;這不會改變游戲規則,但當您在緊密回圈中迭代集合時可能會增加幾微秒。
話雖如此,我建議不要完全放棄在容器中存盤指標,例如sync.Map:偶爾它會派上用場——例如,為了切片重用陣列,您通常存盤指向此類陣列的第一個元素的指標。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/414521.html
標籤:
上一篇:組合框的默認值未在部分視圖中分配
