Skip to content

cmd/compile: optimize back-to-back append calls #76631

@dsnet

Description

@dsnet

Go version

go1.25

Output of go env in your module/workspace:

n/a

What did you do?

Consider these two benchmarks:

func BenchmarkA(b *testing.B) {
	for b.Loop() {
		out = out[:0]
		out = append(out, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
	}
}

func BenchmarkB(b *testing.B) {
	for b.Loop() {
		out = out[:0]
		out = append(out, 0)
		out = append(out, 1)
		out = append(out, 2)
		out = append(out, 3)
		out = append(out, 4)
		out = append(out, 5)
		out = append(out, 6)
		out = append(out, 7)
		out = append(out, 8)
		out = append(out, 9)
		out = append(out, 0)
		out = append(out, 1)
		out = append(out, 2)
		out = append(out, 3)
		out = append(out, 4)
		out = append(out, 5)
		out = append(out, 6)
		out = append(out, 7)
		out = append(out, 8)
		out = append(out, 9)
	}
}

What did you see happen?

BenchmarkA
BenchmarkA-32    	1000000000	         0.7381 ns/op
BenchmarkB
BenchmarkB-32    	82785476	        14.66 ns/op

BenchmarkB runs much slower than BenchmarkA.

What did you expect to see?

I would expect these to run about the same speed. The capacity may slighter differ, but I don't think that's guaranteed by append. Furthermore, I suspect the compiler could probably pre-compute what the capacity would have been and preserve identical behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions