Search Unity

Is Monobehaviour expensive on its own?

Discussion in 'Scripting' started by Rukas90, Mar 23, 2019.

  1. Rukas90

    Rukas90

    Joined:
    Sep 20, 2015
    Posts:
    169
    Hello there,
    I am making the inventory system in one of my projects and on each Inventory slot game object I added a new Monobehaviour class that I called - InvSlot. That class contains some UI references and a single custom 'UpdateData()' method that I call through Inventory class to update the inventory slot with an item information.

    Even if that InvSlot Monobehaviour class doesn't contain any update methods like Update(), LateUpdate(), FixedUpdate() or OnGUI() for example is it still expensive to have it placed on many multiple objects?
    I'm using this type of system in many different instances and just curious if it has any huge impact on performance.
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    Do you see any impact in profiler, when game is running but idle?
     
    Peter77 likes this.
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    The cost of more MonoBehaviours is in that more memory is technically used, but it's mostly negligible.

    The other cost is that calling GetComponent will have to sift through more components attached to that GameObject, which technically can be a bit slower. But you really only notice it when the number of components starts getting large, or you call GetComponent on it frequently (like in Update).

    And of course if you MonoBehaviour handles common events like Update.

    Otherwise, no, it's not really all that expensive in the grand scheme of things.
     
    Ryiah and Rukas90 like this.
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    Saying that, if I am correct, apparently after 2017.x (or around that version) GetComponent has been even further optimized.
     
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Yeah, they optimized it with a method called 'GetComponentFastPath' (it's an internal method) that takes in a pointer location of the output variable that allows generically setting the output speeding it up.

    It looks like this:
    Code (csharp):
    1.  
    2. [System.Security.SecuritySafeCritical]
    3. public unsafe T GetComponent<T>()
    4. {
    5.     var h = new CastHelper<T>();
    6.     GetComponentFastPath(typeof(T), new System.IntPtr(&h.onePointerFurtherThanT));
    7.     return h.t;
    8. }
    9.  

    This was opposed to the previous version where the generic T was just converted to a System.Type with the 'typeof' command, and then it just used the slower GetComponent(System.Type tp) method.

    But as far as I know, it still iterates its components and doesn't have any hashmap that I know of. And this iteration is what would be impacted by a larger number of components.

    Though unless you're adding tons of components to a given GameObject, and constantly calling GetComponent (rather than caching it in Awake/Start). This really isn't that big a deal.
     
    Rukas90, Ryiah and Antypodish like this.