Array vs List — Compare Array and List performance in C#
In this article I’m going to :
- compare Array and List performance
- explain why this happen
- contiguous and con-contiguous memory allocation
- clear List in right way ; Clear() method is not enough
- list topmost Array and List<T> comparison
In C#, arrays and lists are both objects that can be used to hold variables, but they aren’t interchangeable
What is an Array?
In C#, an array is a structure representing a fixed length ordered collection of values or objects with the same type.
What is a List?
The List<T> is a collection of strongly typed objects that can be accessed by index and having methods for sorting, searching, and modifying list
Create benchmark project:
1- Add a new project, then select Console App and press next
2- In configure your new project fill Project name and Location then press next
3- Choose Framework and press create
For benchmark , I used BenchmarkDotNet package, this package can be install as follow:
Install-Package BenchmarkDotNet -Version 0.13.1
And Nuget page is:
https://www.nuget.org/packages/BenchmarkDotNet/0.13.1
4- Add following class to project
there is 3 methods which have [benchmark] attribute and 3 values is set for Count (10,50,100) which are considered 6 benchmarks in total.
for there is 2 benchmarks for List in first count or size is set and for second one is not set.
5- Change program.cs as follow
6- choose Release and run project, it may long time to finish
here is the result:
as you can see Array performance is better than 2 others, and List with out size or capacity has lowest performance.
Let’s see why this happens
before we dive into we need to know what is Contiguous and Non-contiguous Memory Allocation
What is Contiguous and Non-contiguous Memory Allocation
- Contiguous Memory Allocation :
Contiguous memory allocation is basically a method in which a single contiguous section/part of memory is allocated to a process or file needing it. Because of this all the available memory space resides at the same place together, which means that the freely/unused available memory partitions are not distributed in a random fashion here and there across the whole memory space.
2. Non-Contiguous Memory Allocation :
Non-Contiguous memory allocation is basically a method on the contrary to contiguous allocation method, allocates the memory space present in different locations to the process as per it’s requirements. As all the available memory space is in a distributed pattern so the freely available memory space is also scattered here and there.
This technique of memory allocation helps to reduce the wastage of memory, which eventually gives rise to Internal and external fragmentation.
now let’s return to why this happens
Array:
The contents of an array are stored in contiguous memory.in better word Arrays allow for a contiguous block of homogeneous types and derived types. Their main benefit is that they provide lightning-fast access to reading and writing array elements. Their weak point lies in searching arrays, as each and every element must potentially be visited (in an unsorted array), and the fact that resizing the array requires writing a bit of code.
List:
if we take a look at List class source code we see that it is using array in behind.(source code link at the end of this section). in line 40 which is marked by arrow List is using T[] _items . so at behind it uses benefit of contiguous memory. line 38 there is DefaultCapacity= 4 , this is default length of private array if capacity is not set.
List’s Add() method is :
before adding new item , size of array must be check. if size of private array is not enough AddWithResize and Grow is called(below image).
line 424 checks for new capacity. if private array length is 0 then DefaultCapacity sets for length else array length is doubled, then existing array should be cloned to new array.
this is why GenericListPerformanceWithOutCapacity method has lowest performance.
as you can see a lot of things are happening before adding new item to List ( we check just some of them here), so this is why List performance is less than Array.
How Clear List in right way
another thing which must be considered is clearing List. this is not clear exactly.
consider this block of code
copy and past code in program.cs , put break point for result
it is visible both count and capacity are 10. now let clear numbers list and see result again
count is 0 but capacity is 10, as a result Clear() method doesn’t release memory allocated by List(size of private array in List class). Clear method code is
for release memory allocated by private Array in List class use TrimExcess method
TrimExcess method code is
the topmost Array and List comparison
Below table is the topmost Array and List comparison
(image from https://www.educba.com/c-sharp-array-vs-list/)
more detail:
https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,ca7bce81a50b0aeb
https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs