Optimize wake_on_collision_ended
when large number of collisions are occurring
#508
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
wake_on_collision_ended
use almost as much time asrun_substep_schedule
in some casesSolution
wake_on_collision_ended
, skip the body of the first for loop (oversleeping
) if the following both hold true:Sleeping
componentI believe this is ok because the side-effects of that loop is to remove the
Sleeping
component and to resetTimeSleeping
to zero, which is exactly the condition it now tests for. Therefore, if the entity is already in that state, there's no point in executing the relatively costly if statement here (as mentioned above).Since it now also already knows if the
Sleeping
component is present, I gated thecommands.entity(entity).remove::<Sleeping>();
calls so that it only adds that command if the component is presentIt may also be worth gating the
sleeping
query onWithout<SleepingDisabled>
but I wasn't sure how correct that wasResults
Large numbers of colliders (here, 2500) showed a near 1000x improvement in execution time of

wake_on_collision_ended
, going from multiple milliseconds to a few microseconds when none of the bodies are sleeping:Performance regressed for small numbers of colliders (here, 100), however this is regression at the microseconds level (3.5μs to 15.5μs median), so I posit that this is a worthy tradeoff:(removed; I had the traces backwards)
Changelog
wake_on_collision_ended
systemsleeping
query now includesHas<Sleeping>
Sleeping
component ifHas<Sleeping>
resolved to false