Skip to content

Optimize Ref<_, T> methods when T: Sized #2752

@joshlf

Description

@joshlf

Progress

  • Add benchmarks for Ref methods
  • 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:

zerocopy/src/ref.rs

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions