当前位置: 首页 > 后端技术 > Java

面试官:请问如何优化结构的性能?

时间:2023-04-01 14:04:41 Java

使用内存对齐机制优化结构体性能,精彩!前言里分享了之前的2篇结构文章:10秒改struct性能直接提升15%,品姐夸我厉害和Go语言空结构,这3个妙用,你知道吗?它受到了大家的好评。本篇继续分享进阶内容:结构体的定义大家都很熟悉,要定义一个节省内存空间的结构体并不是一件容易的事。我们必须掌握Go的结构体内存对齐机制,才能做出相应的优化:节省内存,提高性能。让我们看一个例子。让我们定义两个结构。字段是一样的,只是有些字段的顺序稍有调整。但是输出结果却完全不同:单次调序节省了8个字节,太神奇了。typeBadStstruct{Aint32Bint64Cbool}typeGoodStstruct{Aint32CboolBint64}funcmain(){bad:=BadSt{A:10,B:20,C:false}fmt.Println(不安全。sizeof(bad))//输出结果:24good:=GoodSt{A:10,B:20,C:false}fmt.Println(unsafe.Sizeof(good))//输出结果:16}为什么bad占24字节,但good只占16字节?要解决这个问题,就得先了解一下内存对齐机制,然后再深入分析。该原理解释了基本概念。为了让CPU更快的存储和读取各个字段,Go编译器会帮我们对齐结构体的数据。所谓数据对齐就是内存地址的大小是存储数据大小(以字节为单位)的整数倍,这样CPU就可以一次从内存中读取数据,减少读取次数.编译器通过在结构的字段之间填充一些空格来实现对齐。CPU访问内存时,CPU访问内存时,并不是逐字节访问,而是以机器字(word)为单位访问。比如64位CPU的字长(wordsize)是8字节,那么CPU访问内存的单位也是8字节,每次加载的内存数据也是固定的字数,比如8words(64bytes)、16words(128bytes)等对齐不同硬件平台占用的系数大小和对齐值可能不同。每个特定平台上的编译器都有自己默认的“对齐系数”。32位系统的对齐系数为4,64位系统的对齐系数为8。不同类型的对齐系数也可能不同。使用Go语言中的unsafe.Alignof函数返回对应类型的对齐系数。对齐系数符合2^n的规律,最大不会超过8。Printf("string:%d\n",unsafe.Alignof(string("a")))fmt.Printf("int:%d\n",unsafe.Alignof(int(0)))fmt.Printf("int32:%d\n",unsafe.Alignof(int32(0)))fmt.Printf("int64:%d\n",unsafe.Alignof(int64(0)))fmt.Printf("float64:%d\n",unsafe.Alignof(float64(0)))fmt.Printf("float32:%d\n",unsafe.Alignof(float32(0)))}//输出结果://bool:1//string:8//int:8//int32:4//int64:8//float64:8//float32:4.对齐原则成员在结构变量中的偏移量必须是成员大小的整数倍。整个结构体的内存大小必须是最大字节的整数倍(该结构体的内存使用量为1/4/8/16byte...)case分析typeBadStstruct{Aint32Bint64Cbool}BadSt结构体,占用24个字节分析过程:字段A4字节:先计算偏移量,第一个下标为0,0%4=0,整除,先占4字节;字段B8字节:下标4-7,如果不能被8整除,补空,下标8可以整除,所以下标8-15的8个字节用于字段B的存储;字段C的1个字节:下标16,可以被1整除,所以后面的标记16作为字段C的存储;最后,结构域最大字节为8,目前占用17字节,必须是整数倍,所以最后部分需要补7字节,占用24字节,满足条件(对齐原则2)*GoodSt结构,占用16字节typeGoodStstruct{Aint32CboolBint64}分析过程:字段A4字节:先计算偏移量,开头的下标为0,0%4=0,整除,占用4字节优先;字段C1字节:下标4,可以被1整除,所以下标4作为字段C的存储;字段B8字节:下标5-7,如果不能被8整除,填空,下标8可以整除,所以下标8-15的8个字节用于字段B的存储;最后,结构体字段最大字节为8,目前占用16个字节,刚好是整数倍,后面不用填空了。小结通过上面的原理讲解和案例分析,我们发现内存对齐机制并不复杂。可以简单理解为:对齐系数小的字段尽量放在一起,尽量减少填空。掌握内存对齐机制后,优化结构体Struct,调整字段顺序,效果立竿见影。内存对齐其实就是一种典型的用空间换取时间来达到优化目的的方式。牢记对齐原则,结合实际场景分析,减少填空。需要简历优化和就业辅导一起学习的朋友可以私信我,欢迎关注我的公众号:我的文章首发于我的公众号:程序员的升职加薪之旅,欢迎大家关注,第一次阅读我的文章。也欢迎大家关注我,点赞,评论,转发。您的支持是我继续写下去的最大动力!