Skip to content

Is PolyZone faster than a distance check?

mkafrin edited this page Mar 12, 2022 · 9 revisions

That is a very loaded question that can't be accurately answered. Instead, let me ask and answer some more specific questions that might clear things up. If you want the TLDR, read this, but the deep dive is useful IMO, so maybe think about reading it all.

Is a CircleZone running at the same tick (Wait(0) or w/e) faster than a naive distance check?

No, it's slightly slower because of the overhead.

Is a CircleZone, using onPointInOut or onPlayerInOut, faster than a naive distance check?

Practically speaking yes (in most cases), because it takes default actions (like running at a slower tick rate) that most people will not do. Basically, defaults are powerful.

What about BoxZones?

Mostly the same compared to a typical AABB check, with the same practical optimizations as CircleZone, plus a few more (like checking the bounding radius of a zone before doing the rotation and AABB check). Note that BoxZones also handle rotation, and therefore aren't just AABB checks.

What about PolyZones?

Here's where some real stuff is happening. The basics of PolyZones just uses well-established algorithms that have been around for decades or more (winding number, shoelace formula, etc.), but it also employs a spatial partitioning data structure (grid) that is efficiently and lazily built to cover only the zone and can be used to skip the algorithms and get an answer to isPointInside in one step rather than lots (most of the time).

It's important to note that while this partitioning optimization is real and useful, it is not unique or new. It existed before this ever did, and the only part I did without reference to existing work is the lazy construction of the grid, which immensely improved memory usage and startup times when many PolyZones were created.

What about ComboZones?

ComboZones are where the real performance power of this resource is found. It uses the same fundamental concept of spatial partitioning (grid) as PolyZones, but the benefits are more significant. Basically in a ComboZone, the map is split up into grid cells and the zones you put in the ComboZone are placed in all cells that the zone's bounding radius overlaps. Then, when the ComboZone checks what zones the point is inside, it only checks the zones the point is close to. In practical terms (because of defaults like number of cells, etc.) the most this can speed up a check is 1700 times (when zones are relatively evenly dispersed).

However, ComboZone also does a few more practical optimizations that few people do, like caching native calls (i.e. GetEntityCoords) and non-exhaustive checks by default (aka stop checking zones if you get a hit) that also give a nice boost in performance.

Conclusion/TLDR

If you're using PolyZones, they are truly faster than just the naive implementation. If you have lots of zones and have them in a ComboZone, that is truly a lot faster than each of those zones being a plain distance check. If you are using BoxZones or CircleZones outside of a ComboZone, whether or not they're faster is entirely a practical question of how carefully you use distance checks, and these zones mostly exist for convivence and the ability to use them in ComboZones (where the largest speedup is).

A lot of the value in PolyZone is in its convivence, helper functions (like onPlayerInOut), debugging drawing, and more. Performance is simply not the only concern.

So is PolyZone definitely, 100%, in all cases, faster than a distance check? No, there's rarely any absolutes in life. Can it be faster in particular use cases? 100%. Is it faster generally speaking for most people, simply because it takes practical and simple optimization steps by default that most people won't do? Yes.

Hopefully this page will help avoid the misconceptions and lead to better knowledge of what PolyZone is doing and where it might be helpful.