[英]capacity after TrimExcess on List<T>
修剪訪問用於最小化集合的內存例如
List<string> myList = new List<string>();
如果我的包含2項后修剪訪問容量列表將是2
同樣,如果TrimExcess容量分別變為4或5或6,則list包含4或5或6
但如果列表包含3或7或15,為什么在TrimExcess之后容量分別變為4或8或16
即使在此之后,如果我運行以下代碼,我發現了一個更奇怪的行為
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語句僅在i = 3時才為真
任何人都可以讓我知道原因
這是List<T>
的源代碼:
public void TrimExcess() {
int threshold = (int)(((double)_items.Length) * 0.9);
if( _size < threshold ) {
Capacity = _size;
}
}
其中_size
是Count
屬性的后備字段, _items.Length
是Capacity
getter返回的內容。
所以基本上,如果沒有使用超過10%的陣列插槽, TrimExcess
只會將容量設置為Count
。 這就是為什么在你的一些測試中, Count
不等於Capacity
。
評論中的另一個問題:
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
為什么第5行打印8? 空列表以0容量開始。
因此,當您插入第5個元素時,容量從4變為8.如果再插入兩個元素,您將看到容量從8到16。
為什么7號線打印8?
我的回答的第一部分已經回答了這個問題。
現在我們知道為什么在調用TrimExcess
之前容量為8。 由於陣列中未使用的空間*不到10%, TrimExcess
什么都不做,而容量仍為8。
注意:實際上,有12.5%的未使用空間(陣列中有1個空閑插槽/ 8個可能的插槽)。 但是因為7 * 0.9被舍入為整數,所以threshold
變為7.並且因為7 < 7
返回false,所以沒有任何反應。
取自List.TrimExcess上的msdn-Documentation:
但是,重新分配和復制大型List的成本可能相當高,因此如果列表容量超過90%, TrimExcess方法就不會執行任何操作 。 這避免了相對較小的增益導致大的重新分配成本。
這意味着,在大多數情況下,List.TrimExcess()調用不執行任何操作,因此List.Count和List.Capacity之間存在差異
我不知道原因,但我決定找出:
public void TrimExcess()
{
int num = (int) (this._items.Length * 0.9);
if (this._size < num)
{
this.Capacity = this._size;
}
}
這讓我感到驚訝。 如果浪費的空間超過10%,它只會削減集合的容量。 似乎是對常見情況的聰明優化(開發人員在不應該調用TrimExcess
時...)。
修剪自己:
list.Capacity = list.Size;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.