-
Notifications
You must be signed in to change notification settings - Fork 134
Description
Progress
- Add benchmarks for
Refmethods - Optimize methods when
T: Sized
Details
As described in #368, Ref<B, T> currently stores a B with the invariant that the referent has a valid size and alignment for T. This allows us to infallibly produce a &(mut) T at runtime (given an existing Ref as a witness to the size and alignment guarantees). Currently, we use Ptr::try_cast_into_no_leftover to re-compute the &(mut) T and .expect on its result since we know it can't fail:
Lines 624 to 626 in e8eb595
| let ptr = Ptr::from_ref(b.into_byte_slice()) | |
| .try_cast_into_no_leftover::<T, BecauseImmutable>(None) | |
| .expect("zerocopy internal error: into_ref should be infallible"); |
This is expensive. In the long run, we should be able to remove most of this computation by storing the &(mut) T itself rather than the B (see #368), although that only works for some B types.
For the time being, and in order to support all B types, we can at least optimize this for the T: Sized case. In particular, since a &(mut) T has no pointer metadata when T: Sized, we can just short-circuit and cast the B pointer directly to a &(mut) T without performing any runtime checks. In other words, this entirely bypasses Ptr::try_cast_into_no_leftover.
We should also add benchmarks so we can measure the performance impact of this change, which I expect will be substantial.