Skip to content
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

[Merged by Bors] - Use u32 over usize for ComponentSparseSet indicies #4723

Closed
wants to merge 3 commits into from

Conversation

james7132
Copy link
Member

@james7132 james7132 commented May 11, 2022

Objective

Use less memory to store SparseSet components.

Solution

Change ComponentSparseSet to only use Entity::id in it's key internally, and change the usize value in it's SparseArray to use u32 instead, as it cannot have more than u32::MAX live entities stored at once.

This should reduce the overhead of storing components in sparse set storage by 50%.

@james7132 james7132 added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times labels May 11, 2022
@james7132
Copy link
Member Author

james7132 commented May 18, 2022

As @TheRawMeatball stated, the cast is likely inconsequential. Here are the relevant benchmark results, most of these are within a reasonable margin of error, but there are notable speedups in sparse set iteration with the indexes being smaller, and thus a bit more cache friendly.

group                                                    main                                     u32-component-sparse-set
-----                                                    ----                                     ------------------------
add_remove_component/sparse_set                          1.02  1319.4±91.25µs        ? ?/sec      1.00  1291.4±78.07µs        ? ?/sec
add_remove_component_big/sparse_set                      1.02  1500.2±336.32µs        ? ?/sec     1.00  1473.8±321.34µs        ? ?/sec
query_get/50000_entities_sparse                          1.07  1127.2±55.93µs        ? ?/sec      1.00  1053.6±22.41µs        ? ?/sec
query_get_component/50000_entities_sparse                1.02  1287.5±52.23µs        ? ?/sec      1.00  1257.3±167.29µs        ? ?/sec
simple_iter/sparse                                       1.09     61.3±0.32µs        ? ?/sec      1.00     56.1±1.11µs        ? ?/sec
simple_iter/sparse_foreach                               1.12     50.4±0.76µs        ? ?/sec      1.00     44.8±1.89µs        ? ?/sec
sparse_fragmented_iter/base                              1.09     12.8±0.86ns        ? ?/sec      1.00     11.7±1.18ns        ? ?/sec
sparse_fragmented_iter/foreach                           1.03      8.9±0.14ns        ? ?/sec      1.00      8.7±0.31ns        ? ?/sec
world_get/50000_entities_sparse                          1.00    548.2±8.05µs        ? ?/sec      1.00   547.7±13.61µs        ? ?/sec
world_query_for_each/50000_entities_sparse               1.17     95.8±0.91µs        ? ?/sec      1.00     81.9±1.48µs        ? ?/sec
world_query_get/50000_entities_sparse                    1.00   398.2±10.82µs        ? ?/sec      1.00   397.8±11.95µs        ? ?/sec
world_query_iter/50000_entities_sparse                   1.19    102.8±3.31µs        ? ?/sec      1.00     86.7±1.59µs        ? ?/sec

@alice-i-cecile
Copy link
Member

@bevyengine/ecs-team more performance optimizations that are ready to review.

@james7132
Copy link
Member Author

To add to this, a lot of the stored usizes we have could also be u32s. Most notably Archetype::entity_table_rows, which could speed up archetype based iteration in general.

I'll leave this for a separate PR so we can benchmark each part in isolation.

@james7132 james7132 added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 19, 2022
@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request May 30, 2022
# Objective
Use less memory to store SparseSet components.

## Solution
Change `ComponentSparseSet` to only use `Entity::id` in it's key internally, and change the usize value in it's SparseArray to use u32 instead, as it cannot have more than u32::MAX live entities stored at once.

This should reduce the overhead of storing components in sparse set storage by 50%.
@bors bors bot changed the title Use u32 over usize for ComponentSparseSet indicies [Merged by Bors] - Use u32 over usize for ComponentSparseSet indicies May 30, 2022
@bors bors bot closed this May 30, 2022
@alice-i-cecile
Copy link
Member

alice-i-cecile commented May 30, 2022

This appears to have caused a failure on release builds. Investigating now-ish; I'm aiming to submit a fix by the end of the day.

EDIT: @james7132 said they'll tackle this, the problem is with the debug asserts getting compiled in release mode, where the types differ.

Because debug_assert! is implemented as if cfg!(debug_assertions) { assert!(/* ... */) }

james7132 added a commit to james7132/bevy that referenced this pull request Jun 7, 2022
# Objective
Use less memory to store SparseSet components.

## Solution
Change `ComponentSparseSet` to only use `Entity::id` in it's key internally, and change the usize value in it's SparseArray to use u32 instead, as it cannot have more than u32::MAX live entities stored at once.

This should reduce the overhead of storing components in sparse set storage by 50%.
@james7132 james7132 deleted the u32-component-sparse-set branch June 22, 2022 08:22
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective
Use less memory to store SparseSet components.

## Solution
Change `ComponentSparseSet` to only use `Entity::id` in it's key internally, and change the usize value in it's SparseArray to use u32 instead, as it cannot have more than u32::MAX live entities stored at once.

This should reduce the overhead of storing components in sparse set storage by 50%.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants