martisch
This is more of a constraint if the struct contains a comparison that can panic. The panic must happen in order or not at all depending how the fields are listed.
type t struct {
a int64
b any
}
Should not panic on b if a values are already different.For maps with keys that are reflexive with == the Go compiler already optimizes the range loop to a single efficient runtime map clear call: https://go-review.googlesource.com/c/go/+/110055
Copy of part of it:
1) While 387 support isn’t a huge maintenance burden, it does take time away from performance and feature work and represents a fair amount of latent complexity.
2) 387 support has been a regular source of bugs (#36400, #27516, #22429, #17357, #13923, #12970, #4798, just to name a few).
3) 387 bugs often go undetected for a long time because we don’t have builders that support only 387 (so unsupported instructions can slip in unnoticed).
4) Raising the minimum requirement to SSE2 would allow us to also assume many other useful architectural features, such as proper memory fences and 128 bit registers, which would simplify the compiler and runtime and allow for much more efficient implementations of core functions like memmove on 386.
5) We’re exploring switching to a register-based calling convention in Go 1.16, which promises significant performance improvements, but retaining 387 support will definitely complicate this and slow our progress.
The 5) didnt make it into go1.16 but will be focused on again for go1.17.
Copied from reddit: https://www.reddit.com/r/golang/comments/cn2jdh/benchmark_of...
Currently make (runtime.makeslice or runtime.mallocgc or duffzero as part of stack allocation) always zeroes the backing array of slice regardless if the element is written to directly or append to the slice. Not requiring the memclr/zeroing would need a prove pass that proves that before the loop finishes noone can observe the uninitialized value by e.g. re-slicing. Which in general when e.g. interfaces and plugins are involved wont be possible to prove. In the case of pointers the memclr is also not avoidable since the garbage collector might scan that part of the memory (if its heap allocated) any time even while the loop is running. https://github.com/golang/go/blob/e37a1b1ca6afcbe3b02d2dfd59...
There could be effects observed due to the difference of having small slices allocated on the stack vs on the heap and differing zero techniques. E.g. for size = 100 there is a jump to duffzero that clears the stack space for the backing array of the slice: https://godbolt.org/z/wRuF5z while for size = 100000 the backing array is heap allocated and zeroed as part of the runtime.makeslice call.
There is a optimization fusing make+copy (to avoid the memclr) in the pipeline for go1.14 but this would not trigger here either.https://go-review.googlesource.com/c/go/+/146719