Search Unity

List-Speed slower on first access?

Discussion in 'Scripting' started by gfrast, Apr 20, 2017.

  1. gfrast

    gfrast

    Joined:
    May 5, 2014
    Posts:
    30
    Can anyone explain, why the first execution of this Code takes about 4 times longer than every further execution? (Press SpaceBar).

    I thought that when a list is initialized with a given size (in my case: List<Vector2> speedTestList = new List<Vector2>(100000000), there shouldnt be any allocation-issues because the list doesnt need to resize on a "List.Add()"?

    It even makes less sense to me, because i'm stopping the "Contains" function, which shouldnt actually vary that much at all, because the list doesnt change?


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Diagnostics;
    3. using System.Collections.Generic;
    4.  
    5. public class PerformanceMeasure : MonoBehaviour
    6. {
    7.     List<Vector2> speedTestList = new List<Vector2>(100000000);
    8.     Stopwatch sw = new Stopwatch();
    9.  
    10.     // Use this for initialization
    11.     void Update()
    12.     {
    13.         if (Input.GetKeyDown(KeyCode.Space))
    14.         {
    15.             Vector2 tmp2;
    16.  
    17.             // Fill Lists
    18.             for (int i = 0; i < speedTestList.Count; i++) speedTestList.Add(new Vector2(0, i));
    19.  
    20.             sw.Start();
    21.             for (int i = 0; i < speedTestList.Count; i++)
    22.             {
    23.                 if (speedTestList.Contains(new Vector2(0, i)))
    24.                 {
    25.                     tmp2 = new Vector2(0, i);
    26.                 }
    27.             }
    28.  
    29.             sw.Stop();
    30.             speedTestList.Clear();
    31.             UnityEngine.Debug.Log("Elapsed Ticks = " + sw.ElapsedTicks);
    32.             sw.Reset();
    33.         }
    34.     }
    35. }
    36.  
    Thanks a lot upfront!
     
  2. laxbrookes

    laxbrookes

    Joined:
    Jan 9, 2015
    Posts:
    235
    Just a note, List.Add() will resize the list as it appends to the end of the collection.
     
  3. laxbrookes

    laxbrookes

    Joined:
    Jan 9, 2015
    Posts:
    235
    Essentially you are initialising a list of 100000000 empty Vector2 and then appending another 100000000 Vector2 to it.
     
  4. gfrast

    gfrast

    Joined:
    May 5, 2014
    Posts:
    30
    Hmmm... why does it say then, that the List.count is 0 when you Log it before adding the additional 100000000 Vector2?
    Also, the time doesnt change if i perform a List.Clear() before adding the Vector2 into the list.

    EDIT:
    I just noticed a problem when i fill the list... apparently it seems the "filling" is never performed, because the .count is 0 on startup.... double checking now
     
    Last edited: Apr 20, 2017
  5. gfrast

    gfrast

    Joined:
    May 5, 2014
    Posts:
    30
    After editing the List-filling to work properly, the performance check now seem stable every time i perform it.
    @Malleck666 thanks for pointing me into the right direction! :)
     
  6. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    No, it wont. As per MSDN description:
    @gfrast I guess the error stems from this line:
    Code (CSharp):
    1. for (int i = 0; i < speedTestList.Count; i++) speedTestList.Add(new Vector2(0, i));
    You have an extra brace there, it should be:

    Code (CSharp):
    1. for (int i = 0; i < speedTestList.Count; i++)
    2. {
    3.     speedTestList.Add(new Vector2(0, i);
    4. }
     
    laxbrookes likes this.
  7. laxbrookes

    laxbrookes

    Joined:
    Jan 9, 2015
    Posts:
    235
    My misunderstanding!
     
  8. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Actually, your code snippet misses the brace. His snippet is correct.

    However, there is another fatal flaw in his logic which has something to do with the nature of the idea behind a dynamically growing list.
    Just have a look at the condition and the actual code to execute.
    If you happen to start adding elements in that loop when you initially start with 'i < speedTestList.Count == true', you'll be running into an infinite loop. The situation leads to some kind of freeze, while the list actually continues to grow until you run out off memory.
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    No... the list wouldn't fill infinitely.

    It won't fill at all.

    Code (csharp):
    1.  
    2. for(int i = 0; i < lst.Count; i++)
    3.  
    This says, start i at 0, if i is less than the count of the list do containing code, add 1.

    Thing is... i is NEVER less than Count, because the lst is empty!

    0 < 0

    i is never less than!

    If they changed it where the list did have something in it... then yes, then it would always be less than the Count.

    OP... you should be doing something like this:

    Code (csharp):
    1.  
    2. for(int i = 0; i < 10000000; i++)
    3.  
    when you fill it

    Then you can use the 'i < lst.Count' when you iterate it.
     
    eisenpony likes this.
  10. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    This is exactly why foreach loops prevent you from modifying the enumeration while iterating. It's an easy mistake to make.
     
  11. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Erm, that's why I said the following:

    Of course it was 0 when he tested it, otherwise he would have encountered exactly this problem.

    Just wanted to point out that this could happen if the list wasn't empty.:)
     
    Last edited: Apr 20, 2017
  12. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    Ahem, something with being busy with a million things and being tired ^.^ sorry 'bout that, was put off by the missing curly braces.