Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Код
func (m *Some) Reset() { *m = Some{} } // очень грубоне приводит к повторному выделению памяти. В этом легко убедиться:
package main
type Some struct {
A int
B string
}
// go:noinline
func (s *Some) Reset() {
*s = Some{}
}
func main() {
s := &Some{}
s.Reset()
}далее
go tool compile -S t.go
...
"".(*Some).Reset t=1 size=29 args=0x8 locals=0x0
0x0000 00000 (t.go:9) TEXT "".(*Some).Reset(SB), $0-8
0x0000 00000 (t.go:9) NOP
0x0000 00000 (t.go:9) NOP
0x0000 00000 (t.go:9) FUNCDATA $0, gclocals·87d20ce1b58390b294df80b886db78bf(SB)
0x0000 00000 (t.go:9) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (t.go:10) MOVQ "".s+8(FP), AX
0x0005 00005 (t.go:10) MOVQ $0, (AX)
0x000c 00012 (t.go:10) MOVQ $0, 8(AX)
0x0014 00020 (t.go:10) MOVQ $0, 16(AX)
0x001c 00028 (t.go:11) RET(то есть, структура s просто обнуляется, либо таким образом, либо вызовом duff device)
package main
type Some struct {
A []byte // LargeSlice
B []byte // VeryLargeSlice
}
// go:noinline
func (s *Some) Reset() {
*s = Some{}
}
func main() {
s := &Some{
A: make([]byte, 0, 100),
B: make([]byte, 0, 1000),
}
s.Reset()
}
"".(*Some).Reset t=1 size=34 args=0x8 locals=0x0
0x0000 00000 (some.go:9) TEXT "".(*Some).Reset(SB), $0-8
0x0000 00000 (some.go:9) NOP
0x0000 00000 (some.go:9) NOP
0x0000 00000 (some.go:9) FUNCDATA $0, gclocals·87d20ce1b58390b294df80b886db78bf(SB)
0x0000 00000 (some.go:9) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (some.go:10) MOVQ "".s+8(FP), DI
0x0005 00005 (some.go:10) TESTB AL, (DI)
0x0007 00007 (some.go:10) XORPS X0, X0
0x000a 00010 (some.go:10) ADDQ $-16, DI
0x000e 00014 (some.go:10) DUFFZERO $288
0x0021 00033 (some.go:11) RET
s.A = s.A[:0], то куда денется слайс после Reset? Сгорит. Думаю, что сгорит.
Go и Protocol Buffers, ускорение