Open rogpeppe opened 3 years ago
I may be mistaken, but doesnt the following allow growing the capacity accordingly and is optimized to not allocate the make?
s = append(s, make([]T, n)...)
I don’t think the compiler will ever be able to optimise this because each append has effects that are observable outside the function. Compare the following:
https://play.golang.org/p/WvBXW8u1SWk
It is still possible, but tricky. What @rogpeppe is worried about is when both appends cause a grow. In that case, the intermediate growth is not observable and can be skipped. But yes, you do have to write all the appends you can to the original slice.
Nevertheless, @pierrec 's workaround should handle this. I'm not sure if specialized code in the compiler would be worth it.
A very similar case is #25828 We can probably move the missing info from one issue into another (any of the two would suffice) and close the other one. See https://github.com/golang/go/issues/25828#issuecomment-407497073 for some insights.
go1.16
The following function will often incur two allocations, one for each
append
call. However the compiler could potentially know the length of the extra data in advance (len(f) + 4) and hence allocate at most once.Working around this is awkward because to do that properly requires duplication of the
append
capacity-growing algorithm so that the slice will grow by a multiplicative rather than a constant factor. When generics arrive, I'd love to see a function like this in the standard library (that would be useful for #14325 amongst others), but the above optimization would still be useful to avoid using that.Related issues:
14325 - this kind of optimization but with loops
25828 - when several append calls can be fused into one (not the case here)
37694 - relates specifically to arrays