Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Overhead of large number of empty array references?

Discussion in 'Scripting' started by arcandio, Feb 25, 2013.

  1. arcandio

    arcandio

    Joined:
    Aug 30, 2009
    Posts:
    73
    Okay, so I'm working on a map, using a 2d builtin array. I have to preset the size of it, since I can't resize it. I end up with about 50 entries and 970 null entries in the array. Is this going to cause problems on mobile or anything?

    And if that IS going to be a problem, is there a way to copy only what fits from one array into the other? My code is set up to copy the large array into a new, properly sized one, but it seems to overwrite the sizes and replace the small array with the big one wholesale. Any thoughts would be appreciated. Snippet of the offending function follows.

    Code (csharp):
    1. function BuildNodeArray() {
    2.     var i : int = 0;
    3.     var xm : int = 0;
    4.     var zm : int = 0;
    5.     var temp2d : GameObject[,] = new GameObject[32, 32];
    6.     for (var untypedNode in nodeList) {
    7.         var node : GameObject =untypedNode as GameObject;
    8.         var nodeComp : MapNode = node.GetComponent(MapNode);
    9.         var xi : int = 0;
    10.         var zi : int = 0;
    11.         xi = nodeComp.index[0];
    12.         zi = nodeComp.index[1];
    13.         if (xi > xm) {
    14.             xm = xi;
    15.         }
    16.         if (zi > zm) {
    17.             zm = zi;
    18.         }
    19.         //Debug.Log("Pos:"+xi+","+zi);
    20.         temp2d[xi,zi] = node;
    21.         //Debug.Log("node:"+nodeArray[xi,zi]);
    22.         i++;
    23.     }
    24.     nodeArray = new GameObject[xm,zm];
    25.     nodeArray = temp2d;
    26.     //System.Array.Resize.<GameObject>(nodeArray, 32); //this is how you resize a builtin array!
    27.     Debug.Log("Built Node Array: "+nodeList.Length);
    28.    
    29.     for ( var n : GameObject in nodeArray) {
    30.         if (n) {
    31.             //Debug.Log(""+n.name+n.transform.position);
    32.             //Debug.Log("node");
    33.         }
    34.         else {
    35.             Debug.Log("no N");
    36.         }
    37.     }
    38. }
     
  2. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,444
    It has to be a garbage collection performance hit, the question is how much is it?

    Code (csharp):
    1.  
    2. ...
    3. public object[,] array;
    4.  
    5. private void Awake()
    6. {
    7.     var timer = new MicroStopwatch();
    8.     GC.Collect();
    9.     GC.WaitForPendingFinalizers();
    10.  
    11.     long total = 0;
    12.     for (int i = 0; i < 100; i++)
    13.     {
    14.         timer.Reset();
    15.         timer.Start();
    16.         GC.Collect();
    17.         timer.Stop();
    18.         total += timer.ElapsedMicroseconds;
    19.     }
    20.     Debug.Log(total / 100); // prints ~3200
    21.  
    22.     array = new object[1000, 1000];
    23.  
    24.     GC.Collect();
    25.     GC.WaitForPendingFinalizers();
    26.  
    27.     total = 0;
    28.     for (int i = 0; i < 100; i++)
    29.     {
    30.         timer.Reset();
    31.         timer.Start();
    32.         GC.Collect();
    33.         timer.Stop();
    34.         total += timer.ElapsedMicroseconds;
    35.     }
    36.     Debug.Log(total / 100); // prints ~4700
    37. }
    38. ...
    39.  
    I'm not sure I did it properly, but anyway I see the difference. A 2d array of a million null elements adds extra 1500±200 microseconds to the garbage collection time on i5-2500K @4GHz.

    MicroStopwatch class is just a wrapper of System.Diagnostics.Stopwatch
    (http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer)
     
    Last edited: Feb 26, 2013
unityunity