在 golang 中优化数据结构/字对齐填充

与我在 C++ 中学到的类似,我相信填充会导致两个结构的实例大小不同。


type Foo struct {

    w byte //1 byte

    x byte //1 byte

    y uint64 //8 bytes

}

type Bar struct {

    x byte //1 byte

    y uint64 //8 bytes

    w byte// 1 byte

}

func main() {

    fmt.Println(runtime.GOARCH)

    newFoo := new(Foo)

    fmt.Println(unsafe.Sizeof(*newFoo))

    newBar := new(Bar)

    fmt.Println(unsafe.Sizeof(*newBar))

}

输出:


amd64

16

24

  • 定义结构成员时是否有经验法则可以遵循?(如类型大小的升序/降序)

  • 是否有我们可以通过的编译时优化,可以自动处理这个问题?

  • 或者我根本不应该担心这个?


慕哥9229398
浏览 183回答 3
3回答

幕布斯6054654

目前没有编译时优化;这些值在 x64 上填充为 8 个字节。您可以手动排列结构以最佳利用空间;通常是从较大的类型变为较小的类型;例如,8 个连续的字节字段将仅使用 8 个字节,但单个字节将被填充到 8 字节对齐,请考虑: https: //play.golang.org/p/0qsgpuAHHppackage mainimport (    "fmt"    "unsafe")type Compact struct {    a, b                   uint64    c, d, e, f, g, h, i, j byte}// Larger memory footprint than "Compact" - but less fields!type Inefficient struct {    a uint64    b byte    c uint64    d byte}func main() {    newCompact := new(Compact)    fmt.Println(unsafe.Sizeof(*newCompact))    newInefficient := new(Inefficient)    fmt.Println(unsafe.Sizeof(*newInefficient))}如果您考虑到这一点;您可以优化结构的内存占用。

慕尼黑的夜晚无繁华

或者我根本不应该担心这个?是的你应该。这也称为机械同情(请参阅此Go Time 播客片段),因此它还取决于您正在编译的硬件架构。如图所示:“天字节对齐回来咬我”(2014 年 1 月)《关于 Go 切片值的内存对齐》(2016 年 7 月)Go 切片中的值是 16 字节对齐的。它们不是 32 字节对齐的。Go 指针是字节对齐的。

守着一只汪

这取决于您正在开发的应用程序的类型以及这些结构的使用。如果应用程序需要满足一些内存/性能标准,您绝对应该关心内存对齐和填充,但不仅如此 - 有一篇很好的文章https://www.usenix.org/legacy/publications/library/proceedings/als00/2000papers/论文/full_papers/sears/sears_html/index.html突出了最佳 CPU 缓存使用的主题以及结构布局和性能之间的相关性。它突出了缓存行对齐、错误共享等。还有一个不错的 golang 工具https://github.com/1pkg/gopium可以帮助自动化这些优化,看看吧!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go