golang 位元組對齊

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

最近在做一些效能最佳化的工作,其中有個結構體佔用的空間比較大,而且在記憶體中的數量又特別多,就在想有沒有最佳化的空間,想起了 c 語言裡面的位元組對齊,通過簡單地調整一下欄位的順序,就能省出不少記憶體,這個思路在 golang 裡面同樣適用

基本資料大小

在這之前先來看下 golang 裡面基本的類型所佔資料的大小

So(unsafe.Sizeof(true), ShouldEqual, 1)So(unsafe.Sizeof(int8(0)), ShouldEqual, 1)So(unsafe.Sizeof(int16(0)), ShouldEqual, 2)So(unsafe.Sizeof(int32(0)), ShouldEqual, 4)So(unsafe.Sizeof(int64(0)), ShouldEqual, 8)So(unsafe.Sizeof(int(0)), ShouldEqual, 8)So(unsafe.Sizeof(float32(0)), ShouldEqual, 4)So(unsafe.Sizeof(float64(0)), ShouldEqual, 8)So(unsafe.Sizeof(""), ShouldEqual, 16)So(unsafe.Sizeof("hello world"), ShouldEqual, 16)So(unsafe.Sizeof([]int{}), ShouldEqual, 24)So(unsafe.Sizeof([]int{1, 2, 3}), ShouldEqual, 24)So(unsafe.Sizeof([3]int{1, 2, 3}), ShouldEqual, 24)So(unsafe.Sizeof(map[string]string{}), ShouldEqual, 8)So(unsafe.Sizeof(map[string]string{"1": "one", "2": "two"}), ShouldEqual, 8)So(unsafe.Sizeof(struct{}{}), ShouldEqual, 0)
  • bool 類型雖然只有一位,但也需要佔用1個位元組,因為電腦是以位元組為單位
  • 64為的機器,一個 int 佔8個位元組
  • string 類型佔16個位元組,內部包含一個指向資料的指標(8個位元組)和一個 int 的長度(8個位元組)
  • slice 類型佔24個位元組,內部包含一個指向資料的指標(8個位元組)和一個 int 的長度(8個位元組)和一個 int 的容量(8個位元組)
  • map 類型佔8個位元組,是一個指向 map 結構的指標
  • 可以用 struct{} 表示空類型,這個類型不佔用任何空間,用這個作為 map 的 value,可以講 map 當做 set 來用

位元組對齊

結構體中的各個欄位在記憶體中並不是緊湊排列的,而是按照位元組對齊的,比如 int 佔8個位元組,那麼就只能寫在地址為8的倍數的地址處,至於為什麼要位元組對齊,主要是為了效率考慮,而更深層的原理看了一下網上的說法,感覺不是很靠譜,就不瞎說了,感興趣可以自己研究下

// |x---|So(unsafe.Sizeof(struct {    i8 int8}{}), ShouldEqual, 1)

簡單封裝一個 int8 的結構體,和 int8 一樣,僅佔1個位元組,沒有額外空間

// |x---|xxxx|xx--|So(unsafe.Sizeof(struct {    i8  int8    i32 int32    i16 int16}{}), ShouldEqual, 12)// |x-xx|xxxx|So(unsafe.Sizeof(struct {    i8  int8    i16 int16    i32 int32}{}), ShouldEqual, 8)

這兩個結構體裡面的內容完全一樣,調整了一下欄位順序,節省了 33% 的空間

// |x---|xxxx|xx--|----|xxxx|xxxx|So(unsafe.Sizeof(struct {    i8  int8    i32 int32    i16 int16    i64 int64}{}), ShouldEqual, 24)// |x-xx|xxxx|xxxx|xxxx|So(unsafe.Sizeof(struct {    i8  int8    i16 int16    i32 int32    i64 int64}{}), ShouldEqual, 16)

這裡需要注意的是 int64 只能出現在8的倍數的地址處,因此第一個結構體中,有連續的4個位元組是空的

type I8 int8type I16 int16type I32 int32So(unsafe.Sizeof(struct {    i8  I8    i16 I16    i32 I32}{}), ShouldEqual, 8)

給類型重新命名之後,類型的大小並沒有發生改變

轉載請註明出處
本文連結:http://hatlonely.com/2018/03/...

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.