簡體   English   中英

列表上的TrimExcess后的容量<T>

[英]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;
        }
    }

其中_sizeCount屬性的后備字段, _items.LengthCapacity 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容量開始。

  • 插入第一個元素時,容量增加到4,即其默認容量。
  • 插入第五個元素時,容量增加到當前容量的兩倍。 因此,如果容量仍為4,則最多為8。
  • 插入第9個元素后,Capacity再次加倍,依此類推。

因此,當您插入第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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM