Golang 简单的数据对齐可提高程序速度和内存使用率 当前要闻
时间:2023-06-29 10:12:02来源:博客园

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

示例演示

type EmployeeStruct struct {IsPublic boolAge      int64Status   boolName     stringImage    float32}

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

  • IsPublic(boolean) 1 字节
  • Age(int64) 8 字节
  • Status(boolean) 1 字节
  • Name(string) 16 字节
  • Image(float32) 4 字节

总计: 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 字节

  • 周期1第一个属性是IsPublic,数据类型为布尔型bool的大小为 1 个字节。因此,当前周期 1 由属性IsPublic(bool ~ 1 byte)填充。下一个属性是Age,数据类型为int64,int64的大小是8字节,由于第1个周期的剩余内存大小只有7个字节,因此第1个周期无法填充Age属性,因此,会进入第2个周期,但是,“剩余的空间呢,怎么办?”。

  • 周期2第2个周期由Age属性填充,数据类型为int64,大小为8字节,刚好填充满。

  • 周期3第三个属性Status,数据类型为bool,大小为1字节,填充(bool~1 byte),剩余内存大小为7字节,然后,下一个属性是Name,类型为字符串,大小为 16 字节,与周期1的情况相同,因为没有足够的空间容纳下一个属性,所以将在下一个周期中进入。所以意味着有7个字节的内存被浪费了

  • 周期 4 和周期 5第四个是Name,数据类型为字符串,大小为16字节。从图上面看,它将在两个周期中填充,周期 4 中填充 8 个字节,周期 5 中填充 8 个字节。

  • 周期6最后一个属性是Image, 数据类型为float32,大小为4字节,浪费剩余的 4 个字节

最后通过计算统计:

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

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

那么,如何解决呢?

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

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

type EmployeeStruct struct {Name     stringAge      int64Image    float32IsPublic boolStatus   bool}

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

  • 周期 1 和周期 2第一个属性是Name,数据类型为字符串,大小为16字节。因此,它将在两个周期中填充,周期 1 中填充 8 个字节,周期 2 中填充 8 个字节。

  • 周期3第3个周期由Age属性填充,数据类型为int64,大小为8字节

  • 周期4下一个属性是Image,数据类型为float32,大小为4字节。因此,当前周期 4 由属性 Image ( float32 ~ 4 字节)填充,剩余大小为 4 字节。

下一个属性是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

标签:

  • 上一篇文章: 鸡西2023年一级建造师考试报名通知
  • 下一篇文章: 最后一页
  • 生活指南
  • 全球消息!MWC上海开幕 喜迎十周年庆典

    中关村在线消息,2023年6月28日,通信互联盛会MWC上海今日在上海新国际

  • 热讯:米兰锁定英格兰中场神将,托纳利替身,皮奥利钦点,3大豪强抢人

    如果AC米兰能从切尔西手里签下洛夫图斯-奇克,无疑为托纳利找到了一个

  • 当前观点:1200公里续航+越野能力!方程豹首款车型神秘标识揭晓

    近日,比亚迪旗下新定名的“方程豹”品牌将搭载全新专属平台——DM-o。

  • 漆黑的魅影气息头巾_气息头巾-天天日报

    1、二周目的城市有卖。2、一周目通关后的大挑战地区也有地方兑换。本文

  • 002392

    本文内容是由小编为大家搜集关于002392,以及的资料,整理后发布的内容

  • 天天即时:人民财评:文旅市场复苏势头强劲 继续释放消费潜力

    热闹的端午节假期刚刚过去,经文化和旅游部数据中心综合测算,今年端午

  • 招联逾期3年怎么办?可以不还利息吗?

    现在很多人都有借网贷的习惯,但是借了之后逾期还款是一个严重的违约行

  • 世界简讯:SMM 上海及其他1#铅市场午评:沪铅逼近15700元/吨 而现货市场交投两淡

    SMM6月26日讯:上海市场驰宏铅15620-15640元 吨,对沪期铅2307合约升水0-20元

  • 怎样查询购房网签是否成功?网签后还会查购房资格吗?

    网签就是买卖双方签订购房合同后,到房地产相关部门进行备案,并公

  • 发放消费券8000万元 端午假期江西商贸消费持续升温

    中新网南昌6月25日电 (记者 吴鹏泉)记者25日从江西省商务厅获悉,

  • 全球聚焦:I华恒股份回复问询超时被终止审核,股权代持与纠纷屡被关注

    两家公司在问询后撤材料。6月19日~6月25日当周(下同),A股有3家拟IPO

  • 世界速讯:十分励志!父母背着上学的脑瘫女孩超一本线32分

    十分励志!父母背着上学的脑瘫女孩超一本线32分

  • 天天热文:债券利率越高越好吗? 债券利率计算公式是什么?

    债券利率越高越好吗?债券利率虽然会直接影响债券投资收益,但债券利

  • 基金建仓是什么意思?基金建仓期大约多少天?

    基金建仓是什么意思?基金建仓是指一只新基金公告发行后,在认购结束

  • 2023河北高考专科分数线公布: 492 环球快消息

    2023河北高考录取分数线2023河北高考批次历史类物理类本科批430439特殊

  • 强降雨袭多地,6月24日预报 每日速看

    新一轮强降雨滚滚来袭,暴雨大雨分布在下列地区,6月24号天气预报今天

  • 民生
    • 精彩看点:证监会:中止万达商管公开发行公司债券注册程序

    • 2023福建广电网络股份有限公司连江分公司招聘公告

    • 鲁山县:野生“茶叶”火爆市场供不应求

    • 百万医疗险买哪个公司的好?来看看这两个