Skip to content

runtime: map[int64]struct{} requires 16 bytes per slot #71368

@prattmic

Description

@prattmic

With swissmaps in 1.24, a map[int64]struct{} requires 16 bytes of space per slot, rather than the expected 8 bytes.

This is an unfortunate side effect of the way the storage is defined internally https://cs.opensource.google/go/go/+/master:src/cmd/compile/internal/reflectdata/map_swiss.go;l=30

	// type group struct {
	//     ctrl uint64
	//     slots [abi.SwissMapGroupSlots]struct {
	//         key  keyType
	//         elem elemType
	//     }
	// }

elemType is struct{}. The struct size rules in the compiler say that if struct ends in a zero-size type, that field is given 1 byte of space (in case someone creates a pointer to the last field, we don't want that to point past the end of allocation).
Then, keyType needs 8-byte alignment, so the last field actually ends up using a full 8-bytes.

This is the most extreme case of KVKVKVKV wasting space due to alignment requirements. We could probably fix this specific case by deconstructing the array+struct in this internal definition, then we'd only need the extra 8 bytes for the last slot.

Note that #70835 considers changing the layout entirely (putting all keys together), which would also fix this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions