Skip to content

Sparse set components in filters force sparse set iteration #2144

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

Open
alice-i-cecile opened this issue May 11, 2021 · 2 comments
Open

Sparse set components in filters force sparse set iteration #2144

alice-i-cecile opened this issue May 11, 2021 · 2 comments
Labels
A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!

Comments

@alice-i-cecile
Copy link
Member

To refresh on sparse sets vs table component storages:

  • Table iteration is 2-4x faster than sparse set iteration at the moment.
  • Adding and removing sparse set components is faster than tables.

If a query has any sparse set components, we must use sparse set iteration as we don't have a single query. This is suboptimal if the sparse set components only exist in the filters, e.g Query<&Dense, With<Sparse>. All of the actual data we need to iterate over exists in table storage though, so this is a needless cost.

This is a common and natural pattern, especially if you're using sparse set marker components, so fixing this problem would help ensure that sparse-set components actually accomplish their promised perf benefits in real applications.

@cart raised this on Discord.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times labels May 11, 2021
@cart
Copy link
Member

cart commented May 11, 2021

Quick point of clarity: while the data we actually return is all in the table, the data required by the filter is not in the Table. We either need to store the data in the table (which likely significantly adds to the cost of maintaining the table + archetype moves) or we need to look up the archetype for each table entry as we scan the table and extract the component info required to evaluate the filter. Its very possible that both of these options end up being worse than the current implementation (which does normal sparse iteration in these cases, which means we already have access to the archetype when evaluating filters).

@alice-i-cecile alice-i-cecile added S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! D-Complex Quite challenging from either a design or technical perspective. Ask for help! labels Dec 12, 2021
@james7132
Copy link
Member

james7132 commented May 26, 2022

I made a first attempt at this with #4800, but it's currently unsound due to Fetch::filter_fetch there being infallible. We could make Fetch::filter_fetch return Option<bool> or collapse it via Option::unwrap_or(false). Might try to refine this so we can remove the filter dense checks if need be.

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 D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!
Projects
None yet
Development

No branches or pull requests

3 participants