C# > Advanced C# > Collections and Generics > Array vs List<T>

Understanding Capacity and Count in List<T>

This code snippet demonstrates the difference between Capacity and Count in a List in C#. Understanding these properties helps optimize memory usage and avoid unnecessary reallocations.

Capacity vs Count

  • Count: Represents the number of elements currently stored in the List.
  • Capacity: Represents the total number of elements the List can hold before it needs to allocate more memory.

Demonstration

The code adds elements to a List and demonstrates how the Capacity increases as needed. The Capacity is automatically managed and typically doubles when it runs out of space. The `TrimExcess()` method reduces the capacity to the actual number of elements, freeing up unused memory.

List<int> numbers = new List<int>();
Console.WriteLine($"Initial Capacity: {numbers.Capacity}, Count: {numbers.Count}"); // Output: Initial Capacity: 0, Count: 0

numbers.Add(1);
Console.WriteLine($"After adding one element, Capacity: {numbers.Capacity}, Count: {numbers.Count}"); // Output: After adding one element, Capacity: 4, Count: 1 (Capacity may vary)

numbers.Add(2);
numbers.Add(3);
numbers.Add(4);
Console.WriteLine($"After adding four elements, Capacity: {numbers.Capacity}, Count: {numbers.Count}"); // Output: After adding four elements, Capacity: 4, Count: 4 (Capacity may vary)

numbers.Add(5);
Console.WriteLine($"After adding five elements, Capacity: {numbers.Capacity}, Count: {numbers.Count}"); // Output: After adding five elements, Capacity: 8, Count: 5 (Capacity may vary, doubled)

numbers.TrimExcess();
Console.WriteLine($"After trimming excess capacity, Capacity: {numbers.Capacity}, Count: {numbers.Count}"); //The capacity is set to the actual number of elements in the List<T> , that is, Count. 

Setting Initial Capacity

You can specify an initial capacity when creating a List. This can be useful if you know approximately how many elements you'll be adding, which can reduce the number of reallocations.

List<int> preSizedList = new List<int>(10); // Initial capacity of 10
Console.WriteLine($"Initial Capacity: {preSizedList.Capacity}, Count: {preSizedList.Count}");

Real-Life Use Case

Imagine you are building a system to process incoming network requests. You expect to receive around 1000 requests per second. By initializing your List with an initial capacity of 1000, you can avoid frequent reallocations, improving performance. `List requests = new List(1000);`

Best Practices

  • Set an initial capacity if you have a reasonable estimate of the number of elements you'll be storing.
  • Use TrimExcess() to release unused memory if you know the List won't grow significantly in the future. Be aware that reallocation will occur if the list grows again.
  • Consider the trade-off between memory usage and reallocation frequency.

When to Use Initial Capacity

Use initial capacity when you have a rough estimate of the number of elements. It is beneficial when you want to reduce the frequency of reallocations, which can impact performance.

Memory Consumption

A large capacity wastes memory. Using `TrimExcess()` to reduce the `Capacity` can reduce the memory footprint if the List isn't expected to grow again.

Pros and Cons

  • Pros: Setting initial capacity can reduce reallocations and boost performance.
  • Cons: Setting a capacity that is too high wastes memory.

FAQ

  • What happens if I add more elements to a List than its current capacity?

    The List will automatically reallocate memory, typically doubling its capacity. This operation can take time, so it's best to avoid frequent reallocations by setting an appropriate initial capacity.
  • When should I use `TrimExcess()`?

    Use `TrimExcess()` when you are sure that the List will not grow significantly in the future and you want to reduce its memory footprint. Be aware that reallocation will occur if the List grows again.
  • Does setting an initial capacity guarantee that the List will never reallocate?

    No. Setting an initial capacity only ensures that the List will have at least that much space allocated initially. If you add more elements than the initial capacity, the List will still reallocate memory.