C# 什么定义了内存流的容量
我使用以下代码计算对象(正在填充的列表)的大小:C# 什么定义了内存流的容量,c#,memory,memorystream,capacity,C#,Memory,Memorystream,Capacity,我使用以下代码计算对象(正在填充的列表)的大小: long myObjectSize = 0; System.IO.MemoryStream memoryStreamObject = new System.IO.MemoryStream(); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryBuffer = new System.Runtime.Serialization.Formatters.Bin
long myObjectSize = 0;
System.IO.MemoryStream memoryStreamObject = new System.IO.MemoryStream();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryBuffer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryBuffer.Serialize(memoryStreamObject, myListObject);
myObjectSize = memoryStreamObject.Position;
AmemoryStreamObject
的初始容量为1024
后来(向列表中添加更多元素后)显示为2048。
而且它似乎随着流内容的增加而增加。那么,在这种情况下,容量的用途是什么呢?内存流和列表容量的用途是,底层数据结构实际上是一个数组,数组不能动态调整大小 因此,首先使用一个小(ish)大小的数组,但一旦添加足够的数据,使数组不再足够大,就需要创建一个新数组,将所有数据从旧数组复制到新数组,然后从现在开始切换到使用新数组 创建+复制需要时间,阵列越大,执行此操作所需的时间越长。因此,如果每次都将数组调整到足够大,那么每次写入内存流或向列表中添加新元素时都会有效地进行调整 相反,您有一个容量,说“您可以在调整大小之前使用此值”,以减少必须执行的创建+复制周期数 例如,如果一次向该数组写入一个字节,而不具备这种容量概念,那么每增加一个字节就意味着整个数组的一个完整的创建+复制周期。相反,对于问题中的最后一个屏幕截图,您可以一次写入一个字节,在执行创建+复制循环之前再写入520次 所以这是一个性能优化 另外一个好处是,重复分配稍大的内存块最终会导致内存碎片化,因此可能会出现“内存不足”异常,减少此类分配的数量也有助于避免这种情况
计算此容量的典型方法是每次只将其加倍。这是由内存流的内部实现引起的。Capacity属性是内部缓冲区的大小。如果MemoryStream是使用固定大小的缓冲区创建的,那么这是有意义的。但是在您的情况下,如果缓冲区太小,内存流可能会增长,而实际实现会使缓冲区的大小增加一倍 内存流代码
private bool EnsureCapacity(int value)
{
if (value < 0)
{
throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
}
if (value > this._capacity)
{
int num = value;
if (num < 256)
{
num = 256;
}
if (num < this._capacity * 2)
{
num = this._capacity * 2;
}
if (this._capacity * 2 > 2147483591)
{
num = ((value > 2147483591) ? value : 2147483591);
}
this.Capacity = num;
return true;
}
return false;
}
你有没有试过看文档?
int num = this._position + count;
// snip
if (num > this._capacity && this.EnsureCapacity(num))