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

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

如果您以前写过 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 以字长的倍数读取地址。

ype JadStruct struct.png

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

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

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

这是低效的。

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

例如,一个 2 字节的数据可以存储在内存 0、2 或 4 中,而一个 4 字节的数据可以存储在内存 0、4 或 8 中。

ype BadStruct struct〈.png

通过简单的对齐数据,确保 IdCardNumber 可以在同一个 CPU 周期内检索到变量。

填充是实现数据对齐的关键。操作系统在数据结构之间用额外的字节填充数据以对齐它们。这就是额外内存的来源!

让我们再来看一看 BadStructGoodStruct

image.png

GoodStruct 消耗更少的内存,仅仅是因为它比 BadStruct 有更好的结构体字段顺序。

由于填充,两个数据结构分别变成了 16 字节和 24 字节。

所以,您只需重新排序结构体中的字段,就可以节省额外的内存!

最后,让我们来做一个简单你的基准测试来证明它在速度和内存的区别,结果如下。点击此处您可以获取可运行的代码。

image.png

从结果您可以看出,遍历 GoodStruct 花费的时间确实更少。重新排序结构体字段可以提高程序的内存使用率和速度。

本篇博客带您了解了简单的数据对齐技术,重新排序结构体中你的字段吧!
数据结构的深思熟虑的对齐真的得到了回报。

目录
相关文章
|
存储 物联网 芯片
聊聊身边的嵌入式:点菜机用着好好的,突然挂了,这口锅应该甩给谁?
聊聊身边的嵌入式:点菜机用着好好的,突然挂了,这口锅应该甩给谁?
|
存储 编解码 数据处理
还在为搞不懂笔记本电脑参数而苦恼么?一篇文章就够啦
还在为搞不懂笔记本电脑参数而苦恼么?一篇文章就够啦
268 4
|
Java 程序员 开发者
只用一行代码,你能玩出什么花样?
只用一行代码,你能玩出什么花样?
88 1
|
C语言
无敌!我用【C语言】手搓出了一个体系完整的【员工管理系统】还能玩游戏听音乐?(超详细,附完整源码)
前言:员工管理系统是一款面向公司管理员的管理工具,旨在提供员工信息管理、薪资管理、员工绩效评估、员工福利管理和智能推荐等功能,帮助公司管理员更好地管理员工信息和提高员工工作效率。 这是总体设计大概模型图:
128 0
|
监控 前端开发 关系型数据库
Zabbix套路深,字符集路更滑,大型翻车现场救援过程分享。
Zabbix套路深,字符集路更滑,大型翻车现场救援过程分享。
130 0
|
传感器 监控 物联网
饭碗空空 猫猫流泪 用HaaS Python DIY一个宠物自动投食器 再也不用担心主子挨饿
饭碗空空 猫猫流泪 用HaaS Python DIY一个宠物自动投食器 再也不用担心主子挨饿
190 0
|
算法 NoSQL API
到底该不该看源码(懂这三点儿就够了)
1、不要为了看源码而看源码 2、代码积累到一定程度,遇到问题自然就去查源码了,然后你就看懂了 3、两年内不要刻意去看源码,可以点开简单了解一下就行,前两年疯狂做项目就行了,后期项目做的多了,你自己就会有疑问,每次写代码就会问自己为什么要这样写?底层的原理是什么?很自觉的带着问题就去看源码了,如果你没有这样的疑问,那说明你也不适合去看源码了,写写业务代码,了了一生
175 0
|
人工智能 运维 数据可视化
程序员养家活口接私活必备网站(顺便用技术改变世界)
程序员接私活的原因很多种(挣钱、养家糊口、提升技术等等)。下面整理了一下网站送给最有潜能的你。 提前准备好自己的笔记本和技术呦。
547 0
ADS2020安装陷阱你学废了吗,小白狂喜教程
ADS2020安装陷阱你学废了吗,小白狂喜教程
809 0
ADS2020安装陷阱你学废了吗,小白狂喜教程