If I use built in arrays that I do not fill completely but instead
have a max value, and use a counter int to keep track of the size,
will it be significantly faster than using Lists?
Yes.
I've done experiment with Unity in the past and doing this is totally fine for large amount of items that needs to be looped over every frame such as image processing.
I once made an app that stream HQ Image over the network. It was easy to make with a List
but after I switched to Array
, the number of frames I received per second increased. It also got ride of memory allocation.
The only down side to using Array is that you have to allocate large amount of memory to make sure that it is enough to hold your items. You also have to check if the current item you want to put in the array can fit. If not, you have to create new array with bigger size, then copy old data to the new one.
Unity's blog also has a post that shows the performance different between using Array
and List
to improve the Update()
function. It is really a big performance increase and the Array is about 5x faster than List
in that experiment.
These are the rules I set for myself when working Unity and it still remians to be true even today:
1.If you need to store large items(200k and above) that requires you loop through them every frame, use array and a simple int value that you can use to determine the length of the array.
2.If this is just items about the size of 5,000 and runs only once in a while then use List
.
I modified this code to run in Unity and below is the result.
Array/for: 6726ms (-1295415896)
List/for: 15803ms (-1295415896)
Array/foreach: 8511ms (-1295415896)
List/foreach: 42689ms (-1295415896)
The difference is very important in Unity unlike a normal C# Application.
void Start()
{
List<int> list = new List<int>(6000000);
for (int i = 0; i < 6000000; i++)
{
list.Add(UnityEngine.Random.Range(1, 10));
}
int[] arr = list.ToArray();
int chk = 0;
Stopwatch watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
int len = list.Count;
for (int i = 0; i < len; i++)
{
chk += list[i];
}
}
watch.Stop();
UnityEngine.Debug.Log(String.Format("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk));
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
int len = arr.Length;
for (int i = 0; i < len; i++)
{
chk += arr[i];
}
}
watch.Stop();
UnityEngine.Debug.Log(String.Format("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk));
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in list)
{
chk += i;
}
}
watch.Stop();
UnityEngine.Debug.Log(String.Format("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk));
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in arr)
{
chk += i;
}
}
watch.Stop();
UnityEngine.Debug.Log(String.Format("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk));
}