Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

[Solved]C# list.add() creates garbage with array.resize(), need alternative

Discussion in 'Scripting' started by clearrose, Feb 24, 2016.

  1. clearrose

    clearrose

    Joined:
    Oct 24, 2012
    Posts:
    349
    I was digging though my profiler and i notice that some my scripts that were using lists to randomly pick between to voids. Were causing bad GC, using the deep profile it attitudes the garbage to array.resize()

    Any suggests to alternatives or solutions, would be appreciated.

    Profiler data:

    Screen Shot 2016-02-24 at 1.08.50 PM.png

    My script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class ChangeSquishyName3 : MonoBehaviour
    6. {
    7.     public DestoryOverTime DestorySquishyScript;
    8.  
    9.     //Define a delegate type to match the required method signature
    10.     delegate void RandomObjectNameMethod ();
    11.  
    12.     void CreateVoidList()
    13.     {
    14.         //Create the new list.
    15.         List<RandomObjectNameMethod> PickRandomName = new List<RandomObjectNameMethod> ();
    16.  
    17.         //adding the methods to the list.
    18.         PickRandomName.Add (NewObjectName);
    19.         PickRandomName.Add (KeepOldName);
    20.  
    21.         //call the randomly picked method.
    22.         PickRandomName [Random.Range(0, PickRandomName.Count)] ();
    23.     }
    24.  
    25.     void Start ()
    26.     {
    27.         InvokeRepeating ("CheckIfSquishyIsvisible", 1f, 1f);
    28.     }
    29.  
    30.     public void CheckIfSquishyIsvisible ()
    31.     {
    32.         if (DestorySquishyScript.IsVisible)
    33.         {
    34.             CancelInvoke ("CheckIfSquishyIsvisible");
    35.  
    36.             Invoke("CreateVoidList", 1.5f);
    37.         }
    38.     }
    39.  
    40.     public void NewObjectName ()
    41.     {
    42.         this.gameObject.name = ("Hidden Heart Squishy");
    43.  
    44.         InvokeRepeating ("ResetCheck", 1f, 1f);
    45.     }
    46.  
    47.     public void KeepOldName ()
    48.     {
    49.         this.gameObject.name = this.gameObject.name;
    50.  
    51.         InvokeRepeating ("ResetCheck", 1f, 1f);
    52.     }
    53.  
    54.     public void ResetCheck ()
    55.     {
    56.         if (!DestorySquishyScript.IsVisible)
    57.         {
    58.             CancelInvoke ("ResetCheck");
    59.  
    60.             Invoke ("StartCheckingAgain", 1.5f);
    61.         }
    62.     }
    63.  
    64.     public void StartCheckingAgain ()
    65.     {
    66.         InvokeRepeating ("CheckIfSquishyIsvisible", 1f, 1f);
    67.     }
    68. }
    69.  
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    That's basically how Lists work. There is a constructor that takes an initial capacity. You can use that to set the initial size of the backing array so that it won't resize (until later, maybe).
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Lists are just wrappers for arrays, that resize the array as you need more slots to fill it up.

    They're basically "resizable arrays".

    You need a constant size collection. That's an array.

    Hell, you're going to get garbage because you create the list each time. You're just getting MORE garbage in your example.

    You're also creating garbage by generating those delegates as well.

    Your other option is to not even use a collection. You're randomly selecting between 2 objects... why not just flip for that?

    Code (csharp):
    1.  
    2.     void RandomlyChangeName()
    3.     {
    4.         if(Random.value < 0.5f)
    5.             NewObjectName();
    6.         else
    7.             KeepOldName();
    8.     }
    9.  
    zero garbage
     
  4. clearrose

    clearrose

    Joined:
    Oct 24, 2012
    Posts:
    349

    Thank you very much this worked perfectly.

    New script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class ChangeSquishyName3 : MonoBehaviour
    6. {
    7.     public DestoryOverTime DestorySquishyScript;
    8.  
    9.     void Start ()
    10.     {
    11.         InvokeRepeating ("CheckIfSquishyIsvisible", 1f, 1f);
    12.     }
    13.  
    14.     void randomlyChangeName ()
    15.     {
    16.         Random.Range (0, 1);
    17.  
    18.         if (Random.value < 0.5f)
    19.         {
    20.             NewObjectName ();
    21.         }
    22.  
    23.         else
    24.         {
    25.             KeepOldName ();
    26.         }
    27.     }
    28.  
    29.     public void CheckIfSquishyIsvisible ()
    30.     {
    31.         if (DestorySquishyScript.IsVisible)
    32.         {
    33.             CancelInvoke ("CheckIfSquishyIsvisible");
    34.  
    35.             Invoke ("randomlyChangeName", 1.5f);
    36.         }
    37.     }
    38.  
    39.     public void NewObjectName ()
    40.     {
    41.         this.gameObject.name = ("Hidden Heart Squishy");
    42.  
    43.         InvokeRepeating ("ResetCheck", 1f, 1f);
    44.     }
    45.  
    46.     public void KeepOldName ()
    47.     {
    48.         this.gameObject.name = this.gameObject.name;
    49.  
    50.         InvokeRepeating ("ResetCheck", 1f, 1f);
    51.     }
    52.  
    53.     public void ResetCheck ()
    54.     {
    55.         if (!DestorySquishyScript.IsVisible)
    56.         {
    57.             CancelInvoke ("ResetCheck");
    58.  
    59.             Invoke ("StartCheckingAgain", 1.5f);
    60.         }
    61.     }
    62.  
    63.     public void StartCheckingAgain ()
    64.     {
    65.         InvokeRepeating ("CheckIfSquishyIsvisible", 1f, 1f);
    66.     }
    67. }
    68.