Skip to content

Make DataResponse constructible from &'static M::Yokeable #3020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
robertbastian opened this issue Jan 23, 2023 · 8 comments
Closed

Make DataResponse constructible from &'static M::Yokeable #3020

robertbastian opened this issue Jan 23, 2023 · 8 comments
Assignees
Labels
2.0-breaking Changes that are breaking API changes A-performance Area: Performance (CPU, Memory) C-data-infra Component: provider, datagen, fallback, adapters S-medium Size: Less than a week (larger bug fix or enhancement) T-enhancement Type: Nice-to-have but not required

Comments

@robertbastian
Copy link
Member

robertbastian commented Jan 23, 2023

Thought: Although ZeroFrom doesn't allocate (except for the skeleton hack), it's not completely free, and it shows up in code size benches. We may want to think about making DataPayload copy-on-write where it can retain a reference to the static data that it returns from .get() and only call ZeroFrom when mutation needs to occur (rarer case).

Originally posted by @sffc in #2906 (comment)

@robertbastian
Copy link
Member Author

robertbastian commented Jan 23, 2023

I took a stab at this, but DataResponse's API surface is pretty big, so this gets quite complex.

@Manishearth

@Manishearth
Copy link
Member

Yeah I htink it would be quite complex, I'm not sure if it's worth it.

@sffc
Copy link
Member

sffc commented Jan 23, 2023

I'd like to see this, and I do think it will have good ROI, but if it's too hard to do while keeping API stable, let's just block it on 2.0

@Manishearth
Copy link
Member

I guess I might not actually understand what you are proposing here

@sffc
Copy link
Member

sffc commented Jan 23, 2023

The problem is that Yoke requires the ox to be a concrete type, but it would be cheaper if we didn't need to ZeroFrom when building from a baked provider.

DataPayload is

pub struct DataPayload<M>
where
    M: DataMarker,
{
    pub(crate) yoke: Yoke<M::Yokeable, Option<Cart>>,
}

AnyPayload is

/// Representations of the `Any` trait object.
///
/// **Important Note:** The types enclosed by `StructRef` and `PayloadRc` are NOT the same!
/// The first refers to the struct itself, whereas the second refers to a `DataPayload`.
#[derive(Debug, Clone)]
enum AnyPayloadInner {
    /// A reference to `M::Yokeable`
    StructRef(&'static dyn Any),
    /// A boxed `DataPayload<M>`.
    ///
    /// Note: This needs to be reference counted, not a `Box`, so that `AnyPayload` is cloneable.
    /// If an `AnyPayload` is cloned, the actual cloning of the data is delayed until
    /// `downcast()` is invoked (at which point we have the concrete type).

    #[cfg(not(feature = "sync"))]
    PayloadRc(SelectedRc<dyn Any>),

    #[cfg(feature = "sync")]
    PayloadRc(SelectedRc<dyn Any + Send + Sync>),
}

/// A type-erased data payload.
///
/// The only useful method on this type is [`AnyPayload::downcast()`], which transforms this into
/// a normal `DataPayload` which you can subsequently access or mutate.
///
/// As with `DataPayload`, cloning is designed to be cheap.
#[derive(Debug, Clone, Yokeable)]
pub struct AnyPayload {
    inner: AnyPayloadInner,
    type_name: &'static str,
}

AnyPayload avoids calling ZeroFrom with the extra variant, but we still need to ZeroFrom when converting to DataPayload.

@sffc
Copy link
Member

sffc commented Jan 24, 2023

We could resolve this if we made DataPayload have two variants, a &'static M::Yokeable for one and Yoke<M::Yokeable> for the other. Mutation methods would make DataPayload "switch" to the mutable (Yoke) version and invoke ZeroFrom. But then we should be able to DCE the ZeroFrom impls from the majority of call sites.

@robertbastian
Copy link
Member Author

There's currently no ZeroFrom bound on anything, so we can't really use that.

@sffc
Copy link
Member

sffc commented Jan 24, 2023

There's currently no ZeroFrom bound on anything, so we can't really use that.

Good point.

We could perhaps add a ZeroFrom bound on the relevant methods, but that's a 2.0 change. Let's hold this until then.

@sffc sffc added the 2.0-breaking Changes that are breaking API changes label Jan 24, 2023
@sffc sffc added this to the ICU4X 2.0 milestone Jan 24, 2023
@sffc sffc added A-performance Area: Performance (CPU, Memory) C-data-infra Component: provider, datagen, fallback, adapters S-medium Size: Less than a week (larger bug fix or enhancement) T-enhancement Type: Nice-to-have but not required labels Jan 24, 2023
@robertbastian robertbastian self-assigned this May 31, 2023
@Manishearth Manishearth removed this from icu4x 2.0 Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.0-breaking Changes that are breaking API changes A-performance Area: Performance (CPU, Memory) C-data-infra Component: provider, datagen, fallback, adapters S-medium Size: Less than a week (larger bug fix or enhancement) T-enhancement Type: Nice-to-have but not required
Projects
None yet
Development

No branches or pull requests

3 participants