Я играл с этим кодом
main_var. go
package main
func main() {
const size = 1000000
slice := make([]SomeStruct, size)
for _, s := range slice { // line 7
_ = s
}
}
type_small. go
package main
type SomeStruct struct {
ID0 int64
ID1 int64
ID2 int64
ID3 int64
ID4 int64
ID5 int64
ID6 int64
ID7 int64
ID8 int64
}
Я заметил, что если я добавлю еще 64 бита int64 ID9
(всего 10 * 8 байт = 80 байт) для структуры, for-l oop становится медленнее.
Если я сравнил сборку, он добавил инструкцию для копирования element
// with 9 int64 (72 bytes)
0x001d 00029 (main_var.go:6) LEAQ type."".SomeStruct(SB), AX
0x0024 00036 (main_var.go:6) MOVQ AX, (SP)
0x0028 00040 (main_var.go:6) MOVQ $1000000, 8(SP)
0x0031 00049 (main_var.go:6) MOVQ $1000000, 16(SP)
0x003a 00058 (main_var.go:6) CALL runtime.makeslice(SB)
0x003f 00063 (main_var.go:6) XORL AX, AX
0x0041 00065 (main_var.go:7) INCQ AX
0x0044 00068 (main_var.go:7) CMPQ AX, $1000000
0x004a 00074 (main_var.go:7) JLT 65
0x004c 00076 (main_var.go:7) MOVQ 32(SP), BP
0x0051 00081 (main_var.go:7) ADDQ $40, SP
0x0055 00085 (main_var.go:7) RET
0x0056 00086 (main_var.go:7) NOP
0x0056 00086 (main_var.go:3) CALL runtime.morestack_noctxt(SB)
0x005b 00091 (main_var.go:3) JMP 0
// with 10 int64 (80 bytes), it added DUFFCOPY instruction
0x001d 00029 (main_var.go:6) LEAQ type."".SomeStruct(SB), AX
0x0024 00036 (main_var.go:6) MOVQ AX, (SP)
0x0028 00040 (main_var.go:6) MOVQ $1000000, 8(SP)
0x0031 00049 (main_var.go:6) MOVQ $1000000, 16(SP)
0x003a 00058 (main_var.go:6) CALL runtime.makeslice(SB)
0x003f 00063 (main_var.go:6) MOVQ 24(SP), AX
0x0044 00068 (main_var.go:6) XORL CX, CX
0x0046 00070 (main_var.go:7) JMP 76
0x0048 00072 (main_var.go:7) ADDQ $80, AX
0x004c 00076 (main_var.go:7) LEAQ ""..autotmp_7+32(SP), DI
0x0051 00081 (main_var.go:7) MOVQ AX, SI
0x0054 00084 (main_var.go:7) DUFFCOPY $826 # <-- copy the element
0x0067 00103 (main_var.go:7) INCQ CX
0x006a 00106 (main_var.go:7) CMPQ CX, $1000000
0x0071 00113 (main_var.go:7) JLT 72
0x0073 00115 (main_var.go:7) MOVQ 112(SP), BP
0x0078 00120 (main_var.go:7) ADDQ $120, SP
0x007c 00124 (main_var.go:7) RET
0x007d 00125 (main_var.go:7) NOP
0x007d 00125 (main_var.go:3) CALL runtime.morestack_noctxt(SB)
0x0082 00130 (main_var.go:3) JMP 0
Мне интересно, почему различное поведение для большей структуры (> 80 байт), даже если в обоих случаях элемент слайса не используется.