Skip to content

cmd/compile: possible append inside a method escape analysis optimization #54563

@mateusz834

Description

@mateusz834
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.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions