成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:請說一下如何優化結構體性能?

開發 前端
掌握了內存對齊機制后,結構體Struct的優化,調整下字段順序,效果立竿見影。內存對齊其實就是典型的空間換時間的方式,來達到優化的目的。牢記對齊原則,對實際場景進行分析,減少空白填充。

?前言

之前分享過2篇結構體文章:10秒改struct性能直接提升15%,產品姐姐都夸我好棒? 和 ??Go語言空結構體這3種妙用,你知道嗎??? 得到了大家的好評。

這篇繼續分享進階內容:

結構體的定義,大家都很熟悉,想要定義出更節省內存空間的結構體,可不是一件簡單的事。

我們必須掌握Go的結構體內存對齊機制,才能做出相應的優化:節省內存并提高性能。

先來看個例子

下面定義兩個結構體,字段都一樣,只是部分字段稍微調整了一下順序。

但輸出的結果卻完全不同:一個順序調整就節省了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))//輸出結果:24
good := GoodSt{A: 10, B: 20, C: false}
fmt.Println(unsafe.Sizeof(good))//輸出結果:16
}

為什么bad占用24字節,而good卻只占用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. 結構體變量中成員的偏移量必須是成員大小的整數倍
  2. 整個結構體的內存大小必須是最大字節的整數倍(結構體的內存占用是1/4/8/16byte…)

案例分析

type BadSt struct {
A int32
B int64
C bool
}

BadSt結構體,占用24個字節

圖片

分析過程:

  1. 字段A 4字節:先計算偏移量,最開頭下標為0,0%4=0,正好整除,先占用4個字節;
  2. 字段B 8字節:下標4-7,對8都不能整除,則填充空白,下標8可以整除,所以下標8-15 8個字節為字段B的存儲使用;
  3. 字段C 1字節:下標16,對1可以整除,所以下標16則用作字段C的存儲;
  4. 最后,該結構體字段最大字節為8且目前已占用17字節,要保證是整數倍,所以最后面需要填充7個字節,占滿24字節,才能滿足條件(對齊原則2)。

GoodSt結構體,占用16個字節

圖片

type GoodSt struct {
A int32
C bool
B int64
}

分析過程:

  1. 字段A 4字節:先計算偏移量,最開頭下標為0,0%4=0,正好整除,先占用4個字節;
  2. 字段C 1字節:下標4,對1可以整除,所以下標4則用作字段C的存儲;
  3. 字段B 8字節:下標5-7,對8都不能整除,則填充空白,下標8可以整除,所以下標8-15 8個字節為字段B的存儲使用;
  4. 最后,該結構體字段最大字節為8且目前已占用16字節,正好是整數倍,所以后面不再需要填充空白了。

總結

通過上文的原理講解和案例分析,我們發現內存對齊機制并不復雜。

可以簡單理解為:將對齊系數小的字段,盡可能放在一起,盡量減少空白填充。

掌握了內存對齊機制后,結構體Struct的優化,調整下字段順序,效果立竿見影。內存對齊其實就是典型的空間換時間的方式,來達到優化的目的。牢記對齊原則,對實際場景進行分析,減少空白填充。

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升職加薪之旅
相關推薦

2021-11-08 15:59:01

MyBatis關聯開發

2023-09-12 14:56:13

MyBatis緩存機制

2025-03-10 07:05:07

2021-07-28 10:08:19

類加載代碼塊面試

2021-08-28 09:06:11

Dubbo架構服務

2022-06-07 12:03:33

Java內存模型

2023-02-08 08:32:41

輪詢鎖

2023-02-18 13:34:14

Nacos健康檢查機制

2022-06-06 15:33:20

線程Java釋放鎖

2022-10-10 12:31:37

服務器性能

2024-02-21 16:42:00

2024-02-27 15:23:48

RedLock算法Redis

2020-07-30 07:58:36

加密算法

2021-06-02 11:25:18

線程池Java代碼

2023-12-29 13:45:00

2024-01-29 10:08:11

零拷貝Zero-copyCPU 拷貝

2020-10-15 06:26:24

高并發場景冰河

2019-11-21 08:40:44

面試官優化性能

2023-01-30 15:39:40

GETHTTP

2021-08-02 08:34:20

React性能優化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成年人视频在线免费观看 | 日韩中文一区二区三区 | 精品久久久久久久 | 亚洲美女视频 | 成人小视频在线免费观看 | 全免费a级毛片免费看视频免费下 | 蜜臀久久| 精品视频在线免费观看 | 久久久久国产一区二区三区 | 永久av | 国产xxxx搡xxxxx搡麻豆 | 99久久夜色精品国产亚洲96 | 国产精品久久久久久久免费大片 | 鸡毛片 | 国产大片黄色 | www.国产精| 亚洲精品国产精品国自产在线 | 国产一区二区三区日韩 | 精品毛片| 国产一区在线看 | 午夜影院在线视频 | 亚洲一区电影 | 日韩二区三区 | 亚洲综合二区 | 毛片99 | 久久99精品久久久久久秒播九色 | 亚洲高清电影 | 国产在线观看av | 91大片| 一级黄色播放 | 黑人精品欧美一区二区蜜桃 | 免费精品| 久久99视频精品 | 亚洲有码转帖 | 日韩福利| 国产精品揄拍一区二区 | 黄a大片 | 精品视频一区二区 | 亚洲va国产日韩欧美精品色婷婷 | 国产乱一区二区三区视频 | 欧美成人久久 |