-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
type Builder struct {
buf []byte
}
func (b *Builder) DoSth() {
b.buf = append(b.buf, 1)
}
func escapes() {
b := Builder{make([]byte, 0, 10)}
b.DoSth()
}BenchmarkEscapes-4 48139129 37.46 ns/op 16 B/op 1 allocs/op
func doesNotEscape() {
b := Builder{make([]byte, 0, 10)}
b.buf = append(b.buf, 1)
_ = b
}BenchmarkDoesNotEscape-4 1000000000 0.3443 ns/op 0 B/op 0 allocs/op
I think we might just mark the append function implicitly in compiler as noescaping.
Doing so, but explicitly, removes the allocation:
func (b *Builder) DoSth() {
b.buf = append2(b.buf, 1)
}
//go:noescape
//go:linkname append2 aa.append2helper
func append2(buf []byte, elems ...byte) []byte
func append2helper(buf []byte, elems ...byte) []byte {
return append(buf, elems...)
}BenchmarkNoescapeAppend-4 170689034 7.031 ns/op 0 B/op 0 allocs/op
I think it is safe to do so. I can't think of any case where the slice passed to append must be forced to be heap allocated.
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.