-
Notifications
You must be signed in to change notification settings - Fork 56
Use Zero-Copy in Reflection Database #528
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
base: master
Are you sure you want to change the base?
Conversation
93227a9
to
de8ce8f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I measured the impact by swapping out the global allocator to measure the memory used by the database, and it looks like this would save us 685kb on startup, which amounts to 24% of the memory footprint of the reflection database. At least on startup; no promises that none of the other code involved isn't causing any noise.
Unfortunately though I'm not sure if I can merge this right now. It's a good change, but it's a breaking one for rbx_reflection
and I'm not sure it's worth the performance gain. I'm not going to close this, but a breaking change for a 685kb change in memory feels not worth it. I doubt anyone is running rbx-dom in an environment where they need that memory back urgently.
In terms of implementation, this is mostly fine but I notice a trend with using &Enum::Variant
when pattern matching. Presumably this is to avoid ownership trouble, but probably the right way to do this is either borrowing the value you're matching or using the ref
keyword.
e.g. instead of
match value {
&Enum::Variant(value) => {}
}
you should probably be doing
match &value {
Enum::Variant(value) => {}
}
or Enum::Variant(ref value) => {}
if necessary.
That's fine, you're right that I'm not hurting for 1MB of memory here. I put this together to implement the desired "lifetime borrowing" semantics described in #515 (comment) after I realized I had seen an implementation in another project. If it can be eventually combined with other breaking changes to make a worthwhile upgrade then that's great.
I had always just assumed it would generate the same assembly whether you dereference or bind by reference. I was using the rbx-dom/rbx_binary/src/core.rs Line 386 in 73cc7c3
Without prefixing the match arm with & , the type of alias_for is &&str . If there's a performance reason not to do this that I don't understand then I would love to learn about it. I checked it out in Compiler Explorer and it seems like there is actually a difference: https://godbolt.org/z/5E8KxY1xh I don't really understand what the assembly difference means other than there is one extra instruction using & .
I suspect there could be a misunderstanding, so to be clear, the match value {
&Enum::Variant(variant) => variant
} Equivalent code would be: match value {
Enum::Variant(variant) => *variant
} |
I'll be honest: I don't know either. My preference is entirely just because I consider |
I updated the dereferencing deconstructions I found according to your preference. By the way, what do you think about |
I'm not opposed to that, though the breaking change in rbx-reflection-database doesn't necessarily correspond to one in rbx-reflection. |
This replaces all occurences of
Cow<'a, str>
andString
in rbx_reflection with&'a str
and a#[serde(borrow)]
annotation.The rbx_reflector implementation is rather lazy.No performance impact after the database is initialized, but will have somewhat reduced memory usage for the in-memory database as well as reduced initialization time. There could be little fix-ups I missed because of how coerce-able &str is.Note:
migration
field ofPropertyMigration
is madepub