如何让你的结构体更高效

这篇具有很好参考价值的文章主要介绍了如何让你的结构体更高效。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文中所涉及到的代码运行结果均是在64位机器上执行得到的.

基础知识回顾

在Go中,我们可以使用unsafe.Sizeof(x)来查看变量所占的内存大小。以下是Go内置的数据类型占用的内存大小:

类型 内存大小(字节数)
bool 1
int8/uint8 1
int/uint 8
int32/uint32 4
int64/uint64 8
float32 4
float64 8
complex64 8
complex128 16
指针类型:*T, map,func,chan 8
string 16
interface 16
[]T 24

func main() {
	fmt.Println(unsafe.Sizeof(true))     // 1
	fmt.Println(unsafe.Sizeof(int8(1)))  // 1
	fmt.Println(unsafe.Sizeof(int(1)))   // 8
	fmt.Println(unsafe.Sizeof(int32(1))) // 4
	fmt.Println(unsafe.Sizeof(int64(1))) // 8

	fmt.Println(unsafe.Sizeof(float32(1.0))) // 4
	fmt.Println(unsafe.Sizeof(float64(1.0))) // 8

	a := int(1)
	fmt.Println(unsafe.Sizeof(&a)) // 8

	s := "1234"
	fmt.Println(unsafe.Sizeof(s)) //16

	var b interface{}
	fmt.Println(unsafe.Sizeof(b)) //16

	fmt.Println(unsafe.Sizeof([]string{})) // 24
	fmt.Println(unsafe.Sizeof([]int{}))    // 24
}

简单示例

对于一个结构体,其占用的内存大小应该是其内部多个基础类型占用内存大小之和。但实际情况并非如此,甚至字段顺序不同,结构体的大小也不同:

type Example1 struct {
	a int32 // 4
	b int32 // 4
	c int64 // 8
}

type Example2 struct {
	a int32 // 4
	c int64 // 8
	b int32 // 4
}

type Example3 struct {
	a bool   // 1
	b int8   // 1
	c string // 16
}

func main() {
	fmt.Println(unsafe.Sizeof(Example1{})) // 16
	fmt.Println(unsafe.Sizeof(Example2{})) // 24
    fmt.Println(unsafe.Sizeof(Example3{})) // 24,并不是1+1+16=18
}

为什么会出现上面的情况呢?这就引出了本文的重点:内存对齐

内存对齐

内存对齐(Memory Alignment)是指数据在计算机内存中存储时按照特定规则对齐到内存地址的过程。内存对齐是由计算机硬件和操作系统所决定的,它可以提高内存访问效率和系统性能。

在计算机体系结构中,内存是以字节(byte)为单位进行访问的。数据类型在内存中占用的字节数可以是不同的,例如,整数可能占用2字节、4字节或8字节,而字符可能只占用1字节。

内存对齐的规则要求变量的地址必须是其数据类型字节数的整数倍。例如,如果一个变量的数据类型是4字节(32位),那么它的起始地址必须是4的倍数。

内存对齐的主要目的是优化计算机的内存访问性能。当数据按照对齐要求存储在内存中时,读取和写入操作可以更高效地进行。如果数据没有按照对齐要求存储,计算机可能需要进行多次内存读取操作来获取完整的数据,这会增加访问延迟和降低系统性能。

在编程中,特别是在使用结构体和类的语言中,内存对齐是一个重要的概念。编译器会根据数据类型的对齐要求自动进行内存对齐操作,以确保数据存储的正确性和性能优化。但在某些情况下,可以通过显式地设置对齐属性来控制数据的对齐方式,以满足特定的需求。

需要注意的是,不同的硬件平台和操作系统可能具有不同的内存对齐规则和要求。因此,在开发跨平台应用程序时,应当考虑到这些差异并遵循适当的内存对齐规则。

为什么需要对齐内存

内存对齐是为了提高计算机系统的内存访问效率和性能而存在的。以下是几个需要内存对齐的原因:

  1. 硬件要求:许多计算机硬件和体系结构对内存访问有特定的对齐要求。如果数据没有按照硬件要求进行对齐,可能会导致访问错误、异常或性能下降。通过满足硬件对齐要求,可以确保数据能够按照有效的方式访问,提高系统的稳定性和性能。
  2. 内存访问效率:当数据按照对齐要求存储在内存中时,计算机系统可以更高效地访问这些数据。对齐数据可以减少或避免多次内存访问,提高数据的读取和写入速度。这对于大量的数据操作和高性能计算非常重要。
  3. 缓存性能:现代计算机系统中通常有多级缓存,而缓存的访问是以特定块的方式进行的。内存对齐可以确保数据按照缓存块的大小对齐,使得数据能够更好地利用缓存,减少缓存未命中和读取延迟,提高缓存性能。
  4. 结构体和类的内存布局:结构体和类通常包含多个成员变量,这些变量按照一定的顺序存储在内存中。内存对齐确保结构体和类的成员变量按照正确的顺序和对齐要求进行存储,避免内存空洞和访问错误,保证数据的正确性和一致性。

总之,内存对齐是为了满足硬件要求、提高内存访问效率和性能而引入的机制。通过合理地进行内存对齐,可以提高系统的稳定性、性能和响应速度,并避免潜在的内存访问问题。

如何对齐内存

Go团队开发了一款名为fieldalignment的工具可以帮助我们解决内存对齐的问题。

使用下面的命令安装fieldalignment工具:

$ go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest

还是以上面的代码为例,可以执行下面的命令:

$ fieldalignment main.go  
main.go:14:15: struct of size 24 could be 16  
main.go:20:15: struct with 16 pointer bytes could be 8

也可以使用--fix参数直接修改代码:

$ fieldalignment --fix main.go

修改后的内容如下:

type Example1 struct {
	a int32 // 4
	b int32 // 4
	c int64 // 8
}

type Example2 struct {
	c int64
	a int32
	b int32
}

type Example3 struct {
	c string
	a bool
	b int8
}

如何让你的结构体更高效

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意文章来源地址https://www.toymoban.com/news/detail-473202.html


到了这里,关于如何让你的结构体更高效的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【⑤MySQL函数】:让你的数据库操作更高效(二)

    前言 ✨欢迎来到小K的MySQL专栏,本节将为大家带来MySQL日期时间、条件判断、系统信息、加密、进制转换和IP地址转换函数的讲解 ✨ 一、日期和时间函数 函数 作用 CURDATE(),CURRENT_DATE() 返回当前日期 CURTIME(),CURRENT_TIME() 返回当前时间 NOW(),CURRENT_TIMESTAMP(),LOCALTIME(), SYSDAT

    2024年02月10日
    浏览(26)
  • chatgpt赋能python:Python数值互换:让你的编程更加高效

    Python是一种高级编程语言,其灵活性和易于学习的特点使其在科学计算、数据分析和人工智能等领域变得非常流行。作为Python的用户,很多时候你可能需要将数值类型之间进行转换,这样可以提高你的编程效率。在本文中,我们将介绍Python中数值互换的知识,并提供一些帮助

    2024年02月09日
    浏览(33)
  • 「NTFS:让你的硬盘更安全、更高效!」NTFS文件系统详解,

    NTFS(New Technology File System)是一种现代的文件系统,是Windows操作系统中最常用的文件系统之一。它是一种高效、可靠、安全的文件系统,支持大容量存储、文件加密、压缩、权限控制等功能。本文将详细介绍NTFS文件系统的结构、$Boot文件、$MFT元文件、文件记录、属性的属性

    2024年02月08日
    浏览(33)
  • chatgpt赋能python:重新配置PyCharm,让你的Python编程更加高效

    PyCharm是一个流行的Python集成开发环境,被广泛用于Python编程。但是,有时候我们需要重新配置PyCharm以适应特定的工作需求或优化其性能,这篇文章将讨论如何重新配置PyCharm,以便更好地支持Python编程。 首先,我们需要了解PyCharm的配置选项,这里我们将重点介绍以下几个:

    2024年02月12日
    浏览(30)
  • 掌握这5款 Edge插件,让你的浏览器使用更高效!

    您好,今天我想向您推荐两款不常用的 Edge 插件,它们可以帮助您更高效地浏览网页和管理标签页。这些插件可能不像一些常见的插件那样广为人知,但它们的功能却非常实用。 IHome新标签页插件 下载地址: https://microsoftedge.microsoft.com/addons/detail/ihome%E5%8E%9Fbdtab%E6%96%B0%E6%A0%

    2024年02月04日
    浏览(33)
  • 一文读懂大数据工具Phoenix:让你的数据管理更高效!

    介绍:Phoenix,最初由saleforce开发并开源,后成为Apache基金会的顶级项目。它是一个构建在HBase上的SQL层,可以使用标准的JDBC APIs而不是HBase客户端APIs来创建表、插入数据和查询HBase中的数据。此外,Phoenix还完全使用Java编写,作为HBase内嵌的JDBC驱动,将SQL查询转换为一个或多个

    2024年01月20日
    浏览(30)
  • Nacos 注册中心的设计原理:让你的应用轻松实现高效注册与发现!

    当应用开始脱离单机运行和访问时,服务发现就诞生了。目前的网络架构是每个主机都有⼀个独立的 IP 地址,服务发现基本都是通过某种方式获取到服务所部署的 IP 地址。 DNS 协议是最早将⼀个网络名称翻译为网络 IP 的协议,在最初的架构选型中,DNS+LVS+Nginx 基本满足所有

    2024年02月10日
    浏览(42)
  • 【实战教程】ThinkPHP6分页功能轻松实现,让你的网站更高效!

    ThinkPHP是一款非常流行的PHP开发框架,其最新版本ThinkPHP6在性能和易用性方面都得到了很大的改善。分页功能是网页开发中非常常见的功能,而ThinkPHP6也提供了非常方便的分页方法。本文将介绍如何实现ThinkPHP6的分页功能。 一、了解分页功能 在Web应用程序中,当数据集非常庞

    2024年01月21日
    浏览(36)
  • JAVA Socket实现实时接收TCP消息,让你的服务端通信更高效!

    本文主要介绍如何利用socket实现实时接收服务端发送的TCP消息。 目录 一、需要掌握 二、程序源码 三、运行演示 网络调试助手下载:https://www.aliyundrive.com/s/6Y8L7Wv5sT6 网络通信协议的理解:JAVA socket是基于TCP/IP协议实现的,需要对TCP/IP协议有一定的了解,包括TCP连接的建立、数

    2024年02月11日
    浏览(28)
  • 分享7个漂亮的 JetBrains IDE 代码主题,让你的开发体验更高效愉悦

    让您的 IDE 更漂亮,提高你的工作效率 作为开发者,我们大部分时间都花在看IDE上。除了好看外,美观的IDE还可以提高生产力。 JetBrains是一家专门创建智能开发工具的尖端软件供应商,包括IntelliJ IDEA,PyCharm,Android Studio等。虽然美观的定义取决于个人的观点,但我在这里编

    2024年02月11日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包