Closed datael closed 2 months ago
Correction: This is still an improvement for 100 colliders, though as mentioned in the original post it's in the region of microseconds so isn't particularly notable:
Assuming I'm looking at the correct section of the trace, gating the removal of Sleeping
on the entity actually having it is also an improvement over previous, but this is even more negligible than the 100 collider case
As a sanity check and to rule out that it wasn't something particular in my scene, this is the move_marbles example in avian2d:
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