您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“如何簡單高效的Go struct優化”,內容詳細,步驟清晰,細節處理妥當,希望這篇“如何簡單高效的Go struct優化”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
下面定義兩個結構體,字段都一樣,只是部分字段稍微調整了一下順序。
但輸出的結果,為什么bad占用24字節,而good卻只占用16字節呢?一個順序調整就節省了8個字節,太神奇了
type BadSt struct { A int32 B int64 C bool } type GoodSt struct { A int32 C bool B int64 } func main() { bad := BadSt{A: 10, B: 20, C: false} fmt.Println(unsafe.Sizeof(bad)) good := GoodSt{A: 10, B: 20, C: false} fmt.Println(unsafe.Sizeof(good)) } //輸出結果: //24 //16
想要解開這個問題,我們得先來學習一下內存對齊機制,然后再來進一步分析
基本概念
為了能讓CPU可以更快的存儲與讀取到各個字段,Go編譯器會幫我們把結構體做數據的對齊。所謂的數據對齊,是指內存地址是所存儲數據大小的整數倍(按字節為單位),以便CPU可以一次將該數據從內存中讀取出來,減少了讀取次數。編譯器通過在結構體的各個字段之間填充一些空白已達到對齊的目的。
CPU訪問內存
CPU 訪問內存時,并不是逐個字節訪問,而是以機器字(word)為單位進行訪問。比如 64位CPU的字長(word size)為8bytes,那么CPU訪問內存的單位也是8字節,每次加載的內存數據也是固定的若干字長,如8words(64bytes)、16words(128bytes)等
對齊系數
不同硬件平臺占用的大小和對齊值都可能是不一樣的,每個特定平臺上的編譯器都有自己的默認"對齊系數",32位系統對齊系數是4,64位系統對齊系數是8
不同類型的對齊系數也可能不一樣,使用Go
語言中的unsafe.Alignof
函數可以返回相應類型的對齊系數,對齊系數都符合2^n
這個規律,最大也不會超過8
func main() { fmt.Printf("bool: %d\n", unsafe.Alignof(bool(true))) fmt.Printf("string: %d\n", unsafe.Alignof(string("a"))) fmt.Printf("int: %d\n", unsafe.Alignof(int(0))) fmt.Printf("int32: %d\n", unsafe.Alignof(int32(0))) fmt.Printf("int64: %d\n", unsafe.Alignof(int64(0))) fmt.Printf("float64: %d\n", unsafe.Alignof(float64(0))) fmt.Printf("float32:%d\n", unsafe.Alignof(float32(0))) } //輸出結果: //bool: 1 //string: 8 //int: 8 //int32: 4 //int64: 8 //float64:8 //float32:4
對齊原則
結構體變量中成員的偏移量必須是成員大小的整數倍
整個結構體的內存大小必須是最大字節的整數倍(結構體的內存占用是1/4/8/16byte…)
BadSt結構體,占用24個字節
type BadSt struct { A int32 B int64 C bool }
分析過程:
字段A 4字節:先計算偏移量,最開頭下標為0,0%4=0,正好整除,先占用4個字節;
字段B 8字節:下標4-7,對8都不能整除,則填充空白,下標8可以整除,所以下標8-15 8個字節為字段B的存儲使用;
字段C 1字節:下標16,對1可以整除,所以下標16則用作字段C的存儲;
最后,該結構體字段最大字節為8且目前已占用17字節,要保證是整數倍,所以最后面需要填充7個字節,占滿24字節,才能滿足條件(對齊原則2)。
GoodSt結構體,占用16個字節
type GoodSt struct { A int32 C bool B int64 }
分析過程:
字段A 4字節:先計算偏移量,最開頭下標為0,0%4=0,正好整除,先占用4個字節;
字段C 1字節:下標4,對1可以整除,所以下標4則用作字段C的存儲;
字段B 8字節:下標5-7,對8都不能整除,則填充空白,下標8可以整除,所以下標8-15 8個字節為字段B的存儲使用;
最后,該結構體字段最大字節為8且目前已占用16字節,正好是整數倍,所以后面不再需要填充空白了。
讀到這里,這篇“如何簡單高效的Go struct優化”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。