OverlapSphere and OverlapSphereNonAlloc

Hi ! what is the difference between OverlapSphere and OverlapSphereNonAlloc ?

It’s been said that OverlapSphereNonAlloc does almost the same but generates less garbage.

Does it mean that it’s more efficient in sense of performance ?
There is no an example of implementation of OverlapSphereNonAlloc method in docs. But it seems different from OverlapSphere

In what cases i should use OverlapSpere instead of OverlapSphereNonAlloc and vice versa ?

Thanks in advance !

3 Likes

Eache time you call overlapSphere that code will allocate a new array.

You could optimize this by keeping the same fixed size array and calling overlapSphereNonAlloc instead.

If you notice the method returns the number of colliders hit, so presumably you should pass in a pre-allocated array big enough to store the results, I sincerely don’t know what would happen if you don’t pass a big enough array.

5 Likes

Thanks !
As far as i understood that fixed array will be rewritten each time i call OverlapSphereNonAlloc method ?

yes, supposedly only up to the return value of the method.

You need to experiment with it a little bit as the documentation is, as always, a little bit lacking.

1 Like

OverlapSphere finds all the overlapping colliders, creates a new array, puts the colliders inside of it, and returns that array.

For OverlapSphereNonAlloc, you send in an array, it finds all the overlapping colliders, puts them in the array, and returns how many colliders it found.

So for OverlapSphereNonAlloc, you can re-use the same array for subsequent calls to the same method. OverlapSphere generates a new array each time.

OverlapSphereNonAlloc is generally a better solution, since it doesn’t generate new arrays that slowly fills the memory (causing GC spikes when you run out). There’s some downsides, though:

  • The remaining spaces in the array is not changed, so you have to be careful to only read up to the returned number from the array.
  • If you send in a too small array, you’ll miss data. The order of the returned colliders are not documented, and I doubt it’s consistent, so you might lose the most important results.

OverlapSphereNonAlloc example:

private Collider[] overlapResults = new Collider[10];

private void Update() {
    int numFound = Physics.OverlapSphereNonAlloc(transform.position, 10f, overlapResults);

    for (int i = 0; i < numFound; i++) {
        Debug.DrawLine(transform.position, overlapResults[i].transform.position, Color.red);
    }
}
37 Likes

Well ! So it seems that OverlapSphereNonAlloc is more efficient in comparison to OverlapSphere.
For garbage collector loading at least…

Are there any situations where using of OverlapSphere is more reasonable ?

I sometimes fail to see why people keep answering already answered questions.

We are not in school anymore boy.

Sometimes because they didn’t see a previous post.

Sometimes because they want to give a more in depth answer.

Sometimes because OP has more questions, or still doesn’t fully understand it.

Don’t worry ZZantal, were not in school anymore, we don’t need to get bothered because someone else also answered the question at hand.

…

As for OP’s latest inquiry:

If you’re not doing repeated OverlapSphere calls, you probably won’t cache an array. In which case it’s extra lines of code to create the array, call OverlapSphereNonAlloc, and then toss it out. Might as well just let OverlapSphere create the array.

Also, allowing OverlapSphere in this scenario create said array, it guarantees the array is large enough to fit all results.

15 Likes

There’s aren’t any examples or much explanation since allocating vs. non-allocating functions are standard features of programming (google them!) Unity’s alloc/non-alloc stuff works the regular way. Not having an example is sort of a way to tell you “if you don’t already know how to use this, it’s better you don’t.”

Sure, the purpose of nonallocate is to run a little faster in certain situations. But it’s usually not much gain, it takes a while to learn how, Unity-forums aren’t very good at teaching ComSci tricks (the rest of the internet is fine for it,) and there are probably a lot of much easier tricks to learn that give much better code improvements.

But, if you want to learn “advanced” programming, definitely write down alloc v. non-alloc on one of your notecards and stick it on the bottom of the pile.

Strictly speaking its purpose is not to run faster even if that happens to be an additional gain. Sure, allocations take time, on the other hand the Non-Alloc has to perform various safety-checks.

It’s all about avoidable garbage in the first place.

8 Likes

Thanks to All of You guys !
it became clear for me…

I’m saying garbage is an unimportant detail. My point is the main things we care about are “Is is simpler and less error-prone?” or “Does it let me do something I couldn’t do otherwise?” or the least important “does it run faster?” Out of those, nonAlloc is the last.

Garbage seems to be one of those explanations which just makes things less clear. You get people worrying about it so much they try to avoid new Vector3 (which doesn’t create any sort of garbage.) Plus, I assume Unity has some sort of modern generational garbage system, where there are different types of garbage and short-term isn’t the bad kind.

You would be wrong here. Garbage is a very important performance consideration for any dev working with Unity. Remember we aren’t in an enterprise situation where a few millisecond delay is acceptable. At 60 FPS you have exactly 16.7ms to do everything in a frame. A garbage collection can easily eat enough of your frame budget to cause a noticeable stutter.

You would be wrong again. Unity’s running on an old version of Mono, with an ancient garbage collector. That means every collection scans all of the heap memory.

6 Likes

The non allocate method requires you as a developer to write more boilerplate code. So the regular method is faster to develop with.

Plus sometimes you can’t sensibly reuse the array. If you only call OverlapSphere once, there is no real point to using non allocate.

Finally the non allocate method is more prone to errors. You can send in an array that’s too small, and loose data. You can loose track of where should end the array, and thus use data from a previous run. Or you can replace an array before you are finished with it, thus using data from a future run.

All said, if you don’t need the performance, use the regular method. Non allocate should only be used if you need the performance.

3 Likes

Nope, mark-and-sweep. No generations for you!

It’s apparently being worked on together with the rest of the language upgrade stuff, but there’s no official timeline yet for when we get a GC that’s not decades old.

3 Likes

When called regularly, it is indeed an important detail. If you call it once in a while, just call the allocating version.

In regards to your list, it’s quite the complete opposite:
It’s not simpler: You have to pass an array which should not be null, should be big enough unless you wanna miss results, you should handle the correct further usage of that array instance…
which makes it more error prone.
On top of that it doesn’t allow to do something that the allocating version couldn’t do, except that it avoids garbage.
And it’s also not necessarily faster.

It’s really only about the allocations, that’s where its name originates from.

That almost implies the name itself makes it less clear?

It’s sometimes better to worry a little more than less, given that you actually take the time to look things up in order to decide whether your worries are justified or not.

In your example, one would pretty quickly realize that it’s not an issue and that it might be possible to have missed a fundamental yet important difference between a reference type and a value type.

And Unity’s garbage collector: like already mentioned… don’t count on that. :smile:

Realizing this is a 3-year old necro, this thread is at the top of search results when comparing the difference between Physics.OverlapSphere and Physics.OverlapSphereNonAlloc. @Baste 's relatively recent edits worked perfectly for me.

I wanted to add a pretty important use case for Physics.OverlapSphereNonAlloc, and that is for when you want a super-performant OverlapSphere and you don’t care about the Collider(s) in question, but rather that it simply collided with something. Assign the objects you want to listen for in a layer, then have Physics.OverlapSphereNonAlloc use that layer in a layer mask.

int numberOfColliders;
Collider[] littleArray = new Collider[1];

void myFunction() {
// sphereObject is where you want the center of the sphere; 1f is a float for the radius; littleArray is just there to store any one of the colliders; 1 << 2 is the layer mask (in this example, layer 2)
numberOfColliders = Physics.OverlapSphereNonAlloc(sphereObject.transform.position,1f, littleArray, 1 << 2, QueryTriggerInteraction.Collide);
            if (numberOfColliders > 0) {
                   Debug.Log("Triggered with an object in layer 2");
            }
}

Edit: Physics.CheckSphere works a ton better.
csharp* *// sphereObject is where you want the center of the sphere; 1f is a float for the radius; 1 << 2 is the layer mask (in this example, layer 2) if(Physics.CheckSphere(sphereObject.transform.position,1f, 1 << 2, QueryTriggerInteraction.Collide) { Debug.Log("Triggered with an object in layer 2"); }* *

1 Like

If you just want to know if something/anything is in the sphere… you could just use ‘CheckSphere’:
https://docs.unity3d.com/ScriptReference/Physics.CheckSphere.html

No array needed at all.

5 Likes

Wow, that works a ton better than what I had. That’s super helpful to know - thank you!!