Golang 简单的数据对齐可提高程序速度和内存使用率

博客园  2023-06-28 21:06:39

Golang 中的结构或 struct 是用户定义的类型,允许将可能不同类型的项分组/组合为单一类型。可以说是一个不支持继承但支持组合的轻量级类。我们使用 Golang 编写代码的时候,你肯定使用过struct。但是,你可能不知道的是,通过简单地重新排序结构中的字段,可以极大地提高 Go 程序的速度和内存使用率!

示例演示

type EmployeeStruct struct {IsPublic boolAge      int64Status   boolName     stringImage    float32}

我们来看一下Employee结构体的内存大小:


(相关资料图)

总计: 30 字节

通过unsafe.Sizeof检查一下:

package mainimport ("fmt""unsafe")type EmployeeStruct struct {IsPublic boolAge      int64Status   boolName     stringImage    float32}func main() {var employee EmployeeStructfmt.Println(unsafe.Sizeof(employee))}

执行后输出: 48字节,为什么呢?

处理器类型

我们知道CPU 分为32位、34位,但是,它是如何运作的呢?

想象一下我们有一个 64 位的 CPU,每个时钟周期传输 64 位数据的能力。

时钟周期是CPU处理一个信息需要多少时间,CPU 32位在1个周期内转换4字节数据,CPU 64位在1个周期内转换8字节数据(32位= 4字节,64位= 8字节)

上面我们定义的EmployeeStruct结构体,并且计算得到了每个字段在内存中占用的字节数。下面我们看CPU处理信息需要多少时间呢?先来看下面的一张图:

图里面6个周期,每个周期有八个盒子,表示是CPU处理能力,为 8 字节

最后通过计算统计:

总时钟周期 = 6 个时钟周期结构体大小 = 48 字节浪费的总内存 = 18 字节

所以我们在开发的时候,如果对于一个比较大的数据结构体来说,可能会使结构体的大小变得更大。

那么,如何解决呢?

实际上我们可以根据数据类型的大小来组成序列,最简单的方法是:

按元素内存大小的降序排列字段

type EmployeeStruct struct {Name     stringAge      int64Image    float32IsPublic boolStatus   bool}

这个时候我们再来看一下时间周期:

下一个属性是IsPublic(bool ~ 1 字节)和 Status(bool ~ 1 字节)。因为最后两个属性的总大小只有2个字节,所以我们可以将其放在循环4中。这样一来,循环4就被Image ( float32 ~ 4字节)、IsPublic (bool ~ 1字节)、Status(bool~1 字节)填满了,仅浪费 2 字节内存。

最后通过计算统计:

总时钟周期 = 4 个时钟周期结构体大小 = 32 字节浪费的总内存 = 2 字节

package mainimport ("fmt""unsafe")type EmployeeStruct struct {Name     stringAge      int64Image    float32IsPublic boolStatus   bool}func main() {var employee EmployeeStructfmt.Println(unsafe.Sizeof(employee)) // output: 32}

结束

所以我们在开发的时候,重新排序结构字段是可以提高应用程序的内存使用率和运行速度的。

转载:风向阅读 - Golang 开发技巧 - 简单的数据对齐可提高程序速度和内存使用率地址:https://www.aiweimeng.top/archives/56.html