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
Remove redundent information and optimize dynamic allocations in Table
#12929
base: main
Are you sure you want to change the base?
Remove redundent information and optimize dynamic allocations in Table
#12929
Conversation
…to get rid of code duplication
This reverts commit e4bb500. realize we need the old column back, the new one will be only for tables
…overwriting_component`
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.
Please fix CI, looks like clippy still has the last word, haha. Great job getting this to pass miri!
Only a partial review. Will finish later.
looks like a segfault in |
I like |
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.
We may want to follow this up with a PR for applying ThinColumn for both resources and sparse sets.
…ps_from_table' into remove_lens_and_caps_from_table
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.
Changes look good to me, it's a lot of code but most of it is fairly straightforward and mirrors the other container implementations pretty closely.
I've left some nitpicks that I don't see as blocking, feel free to ignore them.
/// increased. For better unwind safety, call [`BlobVec::set_len`] _after_ populating a new | ||
/// value. | ||
#[inline] | ||
pub unsafe fn set_len(&mut self, len: usize) { |
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.
Why remove the getters/setters?
The fields are private so it's not a big deal, but we lose the ability to annotate safety and so won't get clippy lints encouraging safety comments when people touch the fields.
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.
The primary thing is that they're dead code. They're no longer used in any form as these types are entirely internal. We'd need to add some allow(dead_code)
annotations.
…s_from_table' into remove_lens_and_caps_from_table
Due to the amount of unsafe in this PR, merging now is a potential risk for 0.14, moving this to merge early on in the 0.15 cycle. |
Objective
Table::allocate
fasterSolution
The PR consists of multiple steps:
BlobVec
but doesn't storelen
&capacity
inside of it: "BlobArray" (name suggestions welcome)Tick
data: create a new data-structure that's similar toThinSlicePtr
but supports dynamic reallocation: "ThinArrayPtr" (name suggestions welcome)Column
that doesn't storelen
&capacity
inside of it: "ThinColumn"Table
implementation to useThinColumn
instead ofColumn
The result is that only one set of
len
&capacity
is stored inTable
, inTable::entities
Notes Regarding Performance
Apart from shaving off some excess memory in
Table
, the changes have also brought noteworthy performance improvements:The previous implementation relied on
Vec::reserve
&BlobVec::reserve
, but that redundantly repeated the same if statement (capacity
==len
). Now that check could be made at theTable
level because the capacity and length of all the columns are synchronized; saving N branches per allocation. The result is a respectable performance improvement per everyTable::reserve
(and subsequentlyTable::allocate
) call.I'm hesitant to give exact numbers because I don't have a lot of experience in profiling and benchmarking, but these are the results I got so far:
add_remove_big/table
benchmark after the implementation:add_remove_big/table
benchmark in main branch (measured in comparison to the implementation):add_remove_very_big/table
benchmark after the implementation:add_remove_very_big/table
benchmark in main branch (measured in comparison to the implementation):cc @james7132 to verify
Changelog
BlobVec
but doesn't storelen
&capacity
inside of it:BlobArray
ThinSlicePtr
but supports dynamic allocation:ThinArrayPtr
Column
that doesn't storelen
&capacity
inside of it:ThinColumn
Table
implementation to useThinColumn
instead ofColumn
add_remove_very_big
to benchmark the performance of spawning a lot of entities with a lot of components (15) eachMigration Guide
Table
now usesThinColumn
instead ofColumn
. That means that methods that previously returnedColumn
, will now returnThinColumn
instead.ThinColumn
has a much more limited and low-level API, but you can still achieve the same things inThinColumn
as you did inColumn
. For example, instead of callingColumn::get_added_tick
, you'd callThinColumn::get_added_ticks_slice
and index it to get the specific added tick.