There is a thread on the users forum where someone had a question about the relative performance of “vec!” using a default value of a complex that is zeroed vs creating a vec! of all i16’s (twice the length) and then transmuting to a vec! of complex. There seems to be about a 5x difference in performance for a large vec. Is this something the compiler could optimize better? Is this something that the complex or vec libraries could handle better?
Which comment in that discussion specifically? Since this is information that Vec uses internally to call alloc or alloc_zeroed, I don't really see the point in avoiding unsafe here.
Why is that? If the compile-time size of the type is known (including padding) and you set all the bytes to zero, because it is zeroable, wouldn't that suffice? Or are you referring to how the compiler may be using padding bytes for other purposes?
Only in that it might miss an opportunity for optimization. The behavior will still be correct. The optimization will work for all currently supported is_zero types (because they don’t have padding).
So, if a type had an unsafe marker trait auto-derived (or manually implemented) that indicated that the type was zeroable, you're saying that vec could not rely on that trait to optimize to using the __rust_alloc_zeroed like it would for i16, i32, etc? Or are you saying something else?
#[repr(C)]
struct S {
a: u8,
b: u16
}
let almost_zero: S = transmute([0u8, 13, 0, 0]);
almost_zero does not pass is_mem_zero as defined above, but it would presumably test as zero with a more specialized implementation. However, this is means it’s just a missed opportunity for optimization, using alloc followed by copy is still correct. My proposal for is_mem_zero would allow all current types that use is_zero as well as many user-defined types to use the optimized paths, without requiring any public stabilization of traits or features.