前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10秒改struct性能直接提升15%,产品姐姐都夸我好棒

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

作者头像
机智的程序员小熊
发布2023-03-02 15:15:59
2130
发布2023-03-02 15:15:59
举报
文章被收录于专栏:技术面面观技术面面观

struct 结构体的字段顺序有什么讲究?您可能不知道,通过简单地重新排序结构体中的字段,可以极大地提高 Go 程序的速度和内存使用率!难以置信吧?让我们来看个例子。

例子

ep:

代码语言:javascript
复制
type BadStruct struct {
    age          uint8
    IdCardNumber uint64
    DateOfBirth  uint16
}

type GoodStruct struct {
    age          uint8
    DateOfBirth  uint16
    IdCardNumber uint64
}

在上面的例子中,我们定义了两个具有相同字段的结构体。难以想象他们创建出来的实体不一样大!测试:

代码语言:javascript
复制
func main() {
 var bad BadStruct
 var good GoodStruct

 fmt.Printf("Bad struct is %v bytes long\n", unsafe.Sizeof(bad))
 fmt.Printf("Good struct is %v bytes long", unsafe.Sizeof(good))
}

输出:

代码语言:javascript
复制
Bad struct is 24 bytes long
Good struct is 16 bytes long

居然多了8byte,到底是道德的沦丧,还是人性的扭曲?导致两个字段相同的结构体消耗不同的字节?

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

原理

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

一张调皮的内存对齐示意图

  • 每个格子就是1byte=8bit,64位系统是64bit=8byte。每次CPU访问八个字节的数据。
  • uint81byte占一个格子,占了一个字节,剩下七个。
  • IdCardNumber有八个字节,所以CPU 需要两个周期来访问数据,而不是一个周期。

这是低效的。

所以很多语言都会自动对齐数据,-- 将数据存储在一个地址等于数据大小的倍数的位置。如图:

数据对齐后

这样就能确保 IdCardNumber 可以在同一个 CPU 周期内检索到变量。也正是因为填充了额外的空白数据导致内存膨胀!

回到最初怎么改

对于最初的两个struct,只需要尽可能紧凑,让多个小字段挤在8byte里。如下图:

image.png

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

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

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

来做一个基准测试来证明它在速度和内存的区别结果如下。

基准测试代码

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

国玮在网上找到了两个项目可能和自动校准内存对齐有关,有兴趣可以测测看哦!~

  • https://github.com/robertostling/eflomal
  • https://github.com/essentialkaos/aligo

总结

本次了解了简单的数据对齐技术(内存对齐),重新排序结构体中你的字段吧! 数据结构的深思熟虑的对齐真的得到了回报。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机智的程序员小熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 例子
  • 原理
  • 回到最初怎么改
  • 总结
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档