mirror of
https://github.com/bevyengine/bevy
synced 2024-09-20 06:22:01 +00:00
9bda913e36
# Objective - fix #12853 - Make `Table::allocate` faster ## Solution The PR consists of multiple steps: 1) For the component data: create a new data-structure that's similar to `BlobVec` but doesn't store `len` & `capacity` inside of it: "BlobArray" (name suggestions welcome) 2) For the `Tick` data: create a new data-structure that's similar to `ThinSlicePtr` but supports dynamic reallocation: "ThinArrayPtr" (name suggestions welcome) 3) Create a new data-structure that's very similar to `Column` that doesn't store `len` & `capacity` inside of it: "ThinColumn" 4) Adjust the `Table` implementation to use `ThinColumn` instead of `Column` The result is that only one set of `len` & `capacity` is stored in `Table`, in `Table::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 the `Table` 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 every `Table::reserve` (and subsequently `Table::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:* ![after_add_remove_big_table](https://github.com/bevyengine/bevy/assets/46227443/b667da29-1212-4020-8bb0-ec0f15bb5f8a) *`add_remove_big/table` benchmark in main branch (measured in comparison to the implementation):* ![main_add_remove_big_table](https://github.com/bevyengine/bevy/assets/46227443/41abb92f-3112-4e01-b935-99696eb2fe58) *`add_remove_very_big/table` benchmark after the implementation:* ![after_add_remove_very_big](https://github.com/bevyengine/bevy/assets/46227443/f268a155-295b-4f55-ab02-f8a9dcc64fc2) *`add_remove_very_big/table` benchmark in main branch (measured in comparison to the implementation):* ![main_add_remove_very_big](https://github.com/bevyengine/bevy/assets/46227443/78b4e3a6-b255-47c9-baee-1a24c25b9aea) cc @james7132 to verify --- ## Changelog - New data-structure that's similar to `BlobVec` but doesn't store `len` & `capacity` inside of it: `BlobArray` - New data-structure that's similar to `ThinSlicePtr` but supports dynamic allocation:`ThinArrayPtr` - New data-structure that's very similar to `Column` that doesn't store `len` & `capacity` inside of it: `ThinColumn` - Adjust the `Table` implementation to use `ThinColumn` instead of `Column` - New benchmark: `add_remove_very_big` to benchmark the performance of spawning a lot of entities with a lot of components (15) each ## Migration Guide `Table` now uses `ThinColumn` instead of `Column`. That means that methods that previously returned `Column`, will now return `ThinColumn` instead. `ThinColumn` has a much more limited and low-level API, but you can still achieve the same things in `ThinColumn` as you did in `Column`. For example, instead of calling `Column::get_added_tick`, you'd call `ThinColumn::get_added_ticks_slice` and index it to get the specific added tick. --------- Co-authored-by: James Liu <contact@jamessliu.com> |
||
---|---|---|
.. | ||
bevy_a11y | ||
bevy_animation | ||
bevy_app | ||
bevy_asset | ||
bevy_audio | ||
bevy_color | ||
bevy_core | ||
bevy_core_pipeline | ||
bevy_derive | ||
bevy_dev_tools | ||
bevy_diagnostic | ||
bevy_dylib | ||
bevy_ecs | ||
bevy_encase_derive | ||
bevy_gilrs | ||
bevy_gizmos | ||
bevy_gltf | ||
bevy_hierarchy | ||
bevy_input | ||
bevy_internal | ||
bevy_log | ||
bevy_macro_utils | ||
bevy_math | ||
bevy_mikktspace | ||
bevy_pbr | ||
bevy_picking | ||
bevy_ptr | ||
bevy_reflect | ||
bevy_render | ||
bevy_scene | ||
bevy_sprite | ||
bevy_state | ||
bevy_tasks | ||
bevy_text | ||
bevy_time | ||
bevy_transform | ||
bevy_ui | ||
bevy_utils | ||
bevy_window | ||
bevy_winit |