6
\$\begingroup\$

FindObjectsOfType and FindObjectsByType look very similar, both in name and in usage. The only difference I noticed is that FindObjectsByType takes a sortMode parameter that says:

Whether and how to sort the returned array. Not sorting the array makes this function run significantly faster.

The documentation for FindObjectsOfType recommends using FindObjectsByType instead:

Note: This function is very slow. It is not recommended to use this function every frame. In most cases you can use the singleton pattern instead.

It is recommended to use Object.FindObjectsByType instead. This replacement allows you to specify whether to sort the resulting array. FindObjectsOfType() always sorts by InstanceID, so calling FindObjectsByType(FindObjectsSortMode.InstanceID) produces identical results. If you specify not to sort the array, the function runs significantly faster, however, the order of the results can change between calls.

What are the advantages of one vs the other?

\$\endgroup\$
1
  • \$\begingroup\$ It looks to me like the advantages are pretty clearly spelled out in the documentation that you linked - I've edited the post to include the relevant quotations from those pages to save readers a click, and preserve the current state of the information presented in case the documentation changes in future. What do you find unclear about "FindObjectsOfType is very slow" and "FindObjectByType with FindObjectsSortMode.None is faster"? \$\endgroup\$
    – DMGregory
    Commented Mar 6, 2023 at 15:36

1 Answer 1

12
\$\begingroup\$

When you want to know the rationale for a particular addition to the API, a good place to start is the release notes for the relevant update. I found this just by searching "unity findobjectsbytype":

Scripting: Added: New Object.FindObjectsByType() function added as a potentially faster alternative to Object.FindObjectsOfType(). This new function gives users the choice whether or not to perform the expensive sorting by InstanceID on the returned collection of objects rather than having it always performed, wasting time when unnecessary. See the scripting documentation for Object.FindObjectsByType() and Object.FindObjectsOfType() for more details.

This is similar to the rationale for adding FindFirstObjectByType and FindAnyObjectByType, which were introduced in the same update (2021.3.18).

I'd suspect these additions indicate that under the hood, Unity changed the way that the game objects in open scenes and their components are stored in memory, or the acceleration structures for searching them, in such a way that made it significantly faster to get them in an unordered fashion, but slower to get them in a stable/consistent order. Since for many common use cases we don't care about order, this lets the developer take the fast path when suitable.

They couldn't just change the behaviour of the existing functions though, because that could be a breaking change for old code that relied on the fact that the old methods returned objects in a stable order — wreaking havoc on projects in development that try to update their version, or on who knows how many third-party assets and plug-ins on the Asset Store or tutorials that are not being actively maintained. So they kept the old functions behaving as-is and made a new more explicit API for new code.

I wouldn't be surprised if, in future Unity versions, the old FindObjectOfType/FindObjectsOfType APIs are deprecated, and either automatically upgraded to the equivalent new versions, or made to generate compiler warnings - that way a developer is prompted to examine each call site to determine whether stable ordering is needed for that case, letting them explicitly opt into the fast or slow paths as needed (or refactor their approach if necessary to enable taking the fast path). The team might be giving some time to battle-test the new APIs or stabilize other parts of the engine before taking this step, or giving asset developers time to update voluntarily, so as to minimize the warning spam and disruption when the old API is eventually deprecated. That's just my guess, though.

tl;dr: there's no reason to continue to use the old FindObjectsOfType API. New code should use the more explicit FindObjectsByType API exclusively, making use of the faster FindObjectsSortMode.None option whenever possible.

In rare cases where you do need a stable ordering, passing FindObjectsSortMode.InstanceID makes that requirement explicit, so it's clear you're not taking the slow path by accident, as was possible with FindObjectsOfType.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ See this comment for an explanation of why they added the new API and the deprecation plan for the old API. \$\endgroup\$
    – Kevin
    Commented Mar 30, 2023 at 3:15
  • \$\begingroup\$ Why not add a overload with addition parameters? \$\endgroup\$
    – huang
    Commented Aug 9, 2023 at 13:51
  • \$\begingroup\$ @huang I'd suspect because they know most game developers will keep using the first thing that comes to hand. If you type the familiar FindObjectsOfType() and it's accepted, you don't tend to go looking for an overload that requires typing more characters. So you end up getting "slow by default", when what we really want is "fast by default". As Kevin's link explains, the old function is going to be changed to throw a warning/error to alert to the mistake, and eventually be removed, so that devs can't accidentally stumble into this performance landmine. I think such minesweeping is good. \$\endgroup\$
    – DMGregory
    Commented Aug 9, 2023 at 14:13
  • \$\begingroup\$ @DMGregory "the old function is going to be changed to throw a warning/error to alert to the mistake". Unfortunately, when I wrote the script, I still didn't see any warnings about FindObjectOfType. I use Unity Editor 2022.3 LTS and Visual Studio 2022. \$\endgroup\$
    – huang
    Commented Aug 12, 2023 at 16:54
  • \$\begingroup\$ Right, because the link that Kevin shared says the warnings will be rolled out starting in version 2023.1, and 2022.3 is less than 2023.1. \$\endgroup\$
    – DMGregory
    Commented Aug 12, 2023 at 18:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .