trim access is used minimize a collection's memory For example
List<string> myList = new List<string>();
If my contain 2 items after trim access capacity of list will be 2
in same manner if list contains 4 or 5 or 6 after TrimExcess capacity turns to 4 or 5 or 6 respectively
But if list contain 3 or 7 or 15 why capacity turns to 4 or 8 or 16 respectively after TrimExcess
Even after this I found one more strange behavior if I run the following code
List<int> myList = new List<int>();
for (int i = 1; i <= 100; i++)
{
myList.Add(1);
myList.TrimExcess();
if (myList.Capacity != myList.Count())
{
var different = myList.Capacity;
}
}
if statement get true only if i = 3
Can anyone please let me know the reason
Capacity is the number of elements that the List<T> can store before resizing is required, whereas Count is the number of elements that are actually in the List<T>. Capacity is always greater than or equal to Count.
List size can be increased up to 2 billion (only when your system works on 64-bit or higher) to store large List<T> objects.
Then the TrimExcess method is used to reduce the capacity to match the count, and the Capacity and Count properties are displayed. If the unused capacity had been less than 10 percent of total capacity, the list would not have been resized. Finally, the contents of the list are cleared.
The capacity property in ArrayList class gets or sets the number of elements that the ArrayList can contain. The default capacity is 4. If 5 elements are there, then its capacity is doubled and would be 8.
Here's the source code for List<T>
:
public void TrimExcess() {
int threshold = (int)(((double)_items.Length) * 0.9);
if( _size < threshold ) {
Capacity = _size;
}
}
Where _size
is the backing field for the Count
property and _items.Length
is what the Capacity
getter returns.
So basically, TrimExcess
only sets the capacity to Count
if more than 10% of the array slots are not being used. That's why in some of your tests Count
doesn't equal Capacity
.
Another question from the comments:
1 List<int> myList = new List<int>
2 {
3 1,2,3,4,5,6,7 // equivalent to calling `Add` 7 times
4 };
5 Console.WriteLine(myList.Capacity); // prints 8
6 myList.TrimExcess();
7 Console.WriteLine(myList.Capacity); // prints 8
Why does line 5 print 8? An empty list starts out with 0 Capacity.
So, when you inserted the 5th element, capacity went from 4 to 8. If you insert two more elements, you'll see the capacity going from 8 to 16.
Why does line 7 print 8?
This was already answered in the first part of my answer.
Now we know why Capacity is 8 before calling TrimExcess
.
And because there's less than 10% unused space* in the array, TrimExcess
does nothing, and Capacity remains 8.
Note: Actually, there's 12.5% unused space (1 free slot / 8 possible slots in the array).
But because 7 * 0.9 is rounded to an integer, the threshold
becomes 7. And because 7 < 7
returns false, nothing happens.
Taken from msdn-Documentation on List.TrimExcess:
The cost of reallocating and copying a large List can be considerable, however, so the TrimExcess method does nothing if the list is at more than 90 percent of capacity. This avoids incurring a large reallocation cost for a relatively small gain.
This means, that in most cases your List.TrimExcess() call does nothing, and thus there is a difference between List.Count and List.Capacity
I didn't know the reason but I decided to find out:
public void TrimExcess()
{
int num = (int) (this._items.Length * 0.9);
if (this._size < num)
{
this.Capacity = this._size;
}
}
That was surprising to me. It only trims the capacity of the collection if more than 10% space is wasted. Seems like a clever optimization for the common case (which is developers calling TrimExcess
when they shouldn't...).
Trim yourself:
list.Capacity = list.Size;
It turns out this behavior is even documented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With