Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

why this re-arrange algorithm works? #55

Open
cuiweixie opened this issue Jul 13, 2022 · 1 comment
Open

why this re-arrange algorithm works? #55

cuiweixie opened this issue Jul 13, 2022 · 1 comment

Comments

@cuiweixie
Copy link

structslop/structslop.go

Lines 246 to 267 in 13637e2

sort.Slice(fields, func(i, j int) bool {
ti, tj := fields[i].Type(), fields[j].Type()
si, sj := sizes.Sizeof(ti), sizes.Sizeof(tj)
if si == 0 && sj != 0 {
return true
}
if sj == 0 && si != 0 {
return false
}
ai, aj := sizes.Alignof(ti), sizes.Alignof(tj)
if ai != aj {
return ai > aj
}
if si != sj {
return si > sj
}
return false
})

why sort by <align of field, size of field> can minimize the sizeof struct?
is there some formal prove?

@kirbyquerby
Copy link

kirbyquerby commented Jul 13, 2022

This isn't quite a formal proof, but:

If a struct field would be placed at an offset from the beginning of the struct not divisible by its align, then padding will be inserted between it and the previous field. Because alignments will be to a number of bytes that is a power of 2, a field with an alignment <= the alignment of the previous field will not require padding, since the larger field's alignment is a multiple of the smaller field's alignment. Therefore, sorting by descending alignment should guarantee that there will be no padding between the struct's fields.

There could still be padding at the end of the struct (for example if the last field in a struct has a size smaller than the overall struct's alignment). Interestingly, this means there might still be padding between struct fields if the fields themselves have padding included at the end. Thus, it could be possible to get further savings (at the cost of readability and probably other things) by flattening a struct. For instance: https://go.dev/play/p/ALZhIBGTKbQ

I'm less certain whether having the secondary sorting key be the size of the field, but at the very least, it makes it clear which fields in a struct take up the most space :)

See:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants