Dawn's Blogs

分享技术 记录成长

0%

Go语言高性能编程 (3) 常用数据结构——空结构体和内存对齐

空结构体

在 Golang 中空结构体不占据内存空间。因此可以有以下使用方法:

  • 实现集合:map[string]struct{} 可以实现集合。
  • 用作通知 channel:当 channel 只用于进程同步(通知),不用做传递消息时,可以使用 chan struct{}。
  • 仅包含方法的结构体:结构体只包含方法,不包含任何的字段时(使用 int 或者 bool 都会浪费额外的内存)。

内存对齐

作用

CPU 访问内存时,并不是逐个字节访问,而是以字长(word size)为单位访问。内存对齐可以减少 CPU 的访存次数

memory alignment

Golang 中的对齐

在 Golang 中,unsafe 标准库提供了 Alignof 方法,可以返回一个类型的对齐值(对齐倍数或者对齐数)。

规定如下:

  • 对于任意类型的变量 x,unsafe.Alignof(x) 至少为 1。
  • 对于结构体变量 x,计算每一个字段 f 的对齐值,unsafe.Alignof(x) 为其中每一个字段对齐值的最大值
  • 对于数组型变量 x,unsafe.Alignof(x) 等于构成数组的元素类型的对齐值
  • 空结构体占据空间为 0。

字段顺序影响占用空间

在对内存特别敏感的结构体的设计上,可以通过调整字段的顺序,减少内存的占用

结构体中字段的顺序可能会影响结构体占用的内存空间大小。如下面的例子:

  • 结构体 demo1 对齐倍数为 4,占用的空间大小为 8 字节。
  • 结构体 demo2 对齐倍数为 4,占用的空间大小为 12字节。
1
2
3
4
5
6
7
8
9
10
11
type demo1 struct {
a int8
b int16
c int32
}

type demo2 struct {
a int8
c int32
b int16
}

memory alignment