C# 修剪后的容量超过列表中的容量<;T>;
修剪访问用于最小化集合的内存 比如说C# 修剪后的容量超过列表中的容量<;T>;,c#,C#,修剪访问用于最小化集合的内存 比如说 List<string> myList = new List<string>(); List myList=new List(); 如果我的列表在修剪后包含2项,则列表的访问容量将为2 如果列表中包含4或5或6,则剩余容量将分别变为4或5或6 但若列表包含3、7或15,为什么容量在超出后分别变为4、8或16 即使在这之后,我发现了另一个奇怪的行为 如果我运行以下代码 List<int> myList = new L
List<string> myList = new List<string>();
List myList=new List();
如果我的列表在修剪后包含2项,则列表的访问容量将为2
如果列表中包含4或5或6,则剩余容量将分别变为4或5或6
但若列表包含3、7或15,为什么容量在超出后分别变为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;
}
}
List myList=new List();
对于(int i=1;i取自
然而,重新分配和复制大型列表的成本可能相当大,因此,如果列表的容量超过容量的90%,TrimOverse方法将不起任何作用。这避免了为相对较小的收益而产生巨大的重新分配成本
这意味着,在大多数情况下,List.trimOverse()调用不起任何作用,因此List.Count和List.Capacity之间存在差异我不知道原因,但我决定找出原因:
public void TrimExcess()
{
int num = (int) (this._items.Length * 0.9);
if (this._size < num)
{
this.Capacity = this._size;
}
}
以下是列表的源代码:
为什么第5行打印8?
空列表以0容量开始
- 插入第一个元素时,容量将增加到默认容量4
- 当插入第五个元素时,容量将增加到当前容量的两倍。因此,如果容量仍然为4,则将增加到8
- 插入第9个元素时,容量将再次加倍,依此类推
因此,当您插入第5个元素时,容量从4变为8。如果您再插入两个元素,您将看到容量从8变为16
为什么第7行打印8?
我在回答的第一部分已经回答了这个问题
现在我们知道了为什么在调用TrimOverse
之前容量是8。
由于阵列中的未使用空间*不到10%,因此,trimposure
什么也不做,容量保持在8
注意:实际上,有12.5%的未使用空间(阵列中1个空闲插槽/8个可能的插槽)。
但是因为7*0.9被四舍五入为整数,所以阈值变为7。而且因为7<7
返回false,所以什么也不会发生。列表容量c总是在c中∈ {2^x}|x∈ 如果是这样,那么为什么循环中如果计数为7,则容量在修剪后为7?如果计数为7,则容量在修剪后为8?如果是这样,那么为什么循环中如果计数为7,则容量在修剪后为7?如果计数为7,则容量在修剪后为78@slashshogdhe我不确定我是否理解了你的问题。你能重新表述一下吗?我添加了一个示例,展示了两个用例,其中(Count=7和Capacity=7)和(Count=7和Capacity=8)。当I=7List myList=new List()时,请运行我的代码并检查容量;对于(int I=1;I当I
为7时,计数和容量也为7。有什么奇怪的?
list.Capacity = list.Size;
public void TrimExcess() {
int threshold = (int)(((double)_items.Length) * 0.9);
if( _size < threshold ) {
Capacity = _size;
}
}
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