内存对齐

0 秒改 struct 性能直接提升 15%,产品姐姐都夸我好棒

如果您以前写过 Golang ,那您很可能见过或者写过 Struct 结构体。但是,您可能不知道,通过简单地重新排序结构体中的字段,您可以极大地提高 Go 程序的速度和内存使用率!

难以置信吗?那让我们直接进入正题吧!让我们来看一个例子。如下。

type BadStruct struct {
    age          uint8
    IdCardNumber uint64
    DateOfBirth  uint16
}

type GoodStruct struct {
    age          uint8
    DateOfBirth  uint16
    IdCardNumber uint64
}

在上面的例子中,我们定义了两个具有相同字段的结构体。接下来让我们编写一个简单的程序来输出他们的内存使用情况。点击 此处 您可以获取测试代码。

Bad struct is 24 bytes long
Good struct is 16 bytes long

如您所见,它们占用的内存不同。

到底发生了什么,导致两个字段相同的结构体消耗不同的字节?

答案是数据在操作系统中的内存排列方式。换句话说,数据结构对齐。

CPU 以字长的方式读取数据,而不是通过字节大小。64 位操作系统中一个字长为 8 个字节,而 32 位操作系统中一个字长为 4 个字节。换句话说,CPU 以字长的倍数读取地址。

糟糕的结构体-01
糟糕的结构体-01

在 64 位操作系统中,为了获取变量 IdCardNumber,我们的 CPU 需要两个周期来访问数据,而不是一个周期。

第一个周期将获取到 0 到 7 的内存,其余周期获取其余部分。

把它想象成一个笔记本,每页只能存储一个字大小的数据,此时是 8 个字节。如果 IdCardNumber 分散在两个页面上,则需要翻页两次才能检索完整的数据。

这是低效的。

因此我们需要对齐数据结构,即将数据存储在一个地址等于数据大小的倍数的位置。

Read more