OverlapSphere vs OverlapSphereNonAlloc

Both functions check if there are colliders in a specific radius.

Physics.OverlapSphere creates a new Array each time it is called.

Physics.OverlapSphereNonAlloc takes a Buffer-Array as argument and just fills it when called. That way it causes less Garbage because the same array is reused and thus should be more performant.
The downside is, that OverlapSphereNonAlloc has two important kinks which you need to be aware:

  1. When the supplied buffer-Array is not large enough to store all objects in range, it just stores some random ones in range but not all. (The Documentation isn’t specific about the criteria)
  2. When Objects leave the radius they are not removed from the array. So you have to do it manually.
Physics.OverlapSphere
Physics.OverlapSphereNonAlloc

This is the Script I used for the above test:

public class RangeChecker : MonoBehaviour
{
  [SerializeField] private bool isUsingNonAlloc;
  [SerializeField] Collider[] collidersInRange = new Collider[20];
  private float radius = 10;
  
  void Update()
  {
    if (isUsingNonAlloc)
        Physics.OverlapSphereNonAlloc(transform.position, radius, collidersInRange);
    else
        collidersInRange = Physics.OverlapSphere(transform.position, radius);
  }
}

Performance comparison

In order to make a performance comparison I adjusted the above script, that for the nonallocating Version I clear the items that are no longer in range.

int objInRangeCnt = Physics.OverlapSphereNonAlloc(transform.position, radius, collidersInRange);
for (int i = objInRangeCnt; i < collidersInRange.Length; i++)
    collidersInRange[i] = null;

I created a build and tested it on my computer (AMD Ryzen 5 3600, Radeon RX 6650 XT, 32 Gb Ram).
These are the FPS I’ve got:

Due to the fact that there was almost no difference I also tested OverlapSphereNonAlloc without clearing the array. But even then I only got about ~10% more fps, however I can’t imagine a szenario where it would make sense to not track if elements are no longer in range.

I also created a comparison in the profiler of a developmentbuild when I had 8.192 Rangecheckers. The result: The impact of the Garbagecollector is very small and probably not worth the additional work.

Summary

It seems like it is not worth it to use OverlapSphereNonAlloc in a real-world-szenario even if you have an enormous amount of Overlapspheres per frame.