bevy icon indicating copy to clipboard operation
bevy copied to clipboard

cache ArchetypeId in QueryManyIter and QuerySortedIter

Open Victoronz opened this issue 1 year ago • 0 comments

Objective

When querying for a list of entities, QueryManyIter and QuerySortedIter call D::set_archetype and F::set_archetype with each item fetch (every next() call). Because the vast majority of queries do not have as many archetypes as entities, this is a lot of repeated work. For most QueryData, set_archetype is pretty cheap, but for EntityRef-style types it is implemented as a clone of Access.

Solution

Cache the previous archetype id in the iteration struct, and compare the current archetype id to decide whether to run archetype fetch setup logic.

Consequentially, ìter_many can now perform better than a series of gets. (This was already true, but to a much lesser degree)

Testing

Existing iteration tests.

Potential Future Work

Query::get() is even worse: For EntityRef types, each get() not only constructs an Access with D::init_fetch, but then also clones it twice! By giving Query both a fetch and filter field, D::init_fetch could be avoided in all forms of get() and iter(), and we could perform the same caching trick in all get()s! However, because we do not have dedicated structs like with iteration, the latter runs into mutability issues: fetch/filter` need to be updated for "last archetype id" caching.

Victoronz avatar Nov 30 '24 08:11 Victoronz