Skip to content

Unity OnCollision* handlers are slow and allocate a lot #323

@gotmachine

Description

@gotmachine

Casually checking the state of stock allocations and GC frequency in the Unity profiler, I noticed the Physics.Contacts internal Unity method allocating around 45 kB per frame for a landed 450 parts vessel. Turns out that by default, the Collision object passed to OnCollision* handlers are reallocated for every call to such handlers, which ends up being a lot of allocations due to KSP implementing a lot of (sometimes empty) OnCollisionStay() handlers.

Image

This Unity behavior can actually be changed so Unity can reuse the same Collision object for every call to such callbacks, by toggling the Physics.reuseCollisionCallbacks flag.

However, this is a breaking API change, as if this flag is enabled, the handlers cannot keep a reference to the Collision object outside of their own scope. I haven't verified, but likely this also apply to the Collision.contacts ContactPoint[] array. In stock, the only problematic case seems to be the static VehiclePhysics.VehicleBase.currentCollision static field, part of the Vehicle Physics Pro asset KSP is using for wheels and landing legs.

Further non-Unity profiling would be useful to assess how much actual CPU overhead this is causing, but in any case this seems to be the main remaining source of constant allocations in stock, so getting ride of those would be nice. Pushing such a change would also require assessing which mods are implementing collision handlers and verifying they don't hold references to the Collision object.

A not very extensive GitHub search returned the following problematic cases in mods :

Metadata

Metadata

Assignees

No one assigned

    Labels

    kspPerformancePossible performance improvement in KSP

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions