摘要:使用StringBuilder的注意事項
很多使用者常常使用StringBuilder類別來取代字串的串接,但是StringBuilder本身
的實作方式是以陣列方式來存取字串,預設的Capacity是16,當使用者超出個這個量時,
它會在自行擴增,可是就像陣列一樣,若你常常重新定義陣列大小,實際上是會影響效能的,
因此這時候使用Capacity這個屬性就很重要了,它提供了事先定義StringBuilder的大小。
以下展示StringBulder原始碼如何擴展它的大小 :
System.Text.StringBuilder 原始碼
[SecuritySafeCritical]
internal unsafe StringBuilder Append(char* value, int valueCount)
{
int num = valueCount + this.m_ChunkLength;
if (num <= this.m_ChunkChars.Length)
{
StringBuilder.ThreadSafeCopy(value, this.m_ChunkChars, this.m_ChunkLength, valueCount);
this.m_ChunkLength = num;
}
else
{
// m_ChunkChars.Length = capacity m_ChunkLength = stringbuilder.length
int num2 = this.m_ChunkChars.Length - this.m_ChunkLength;
if (num2 > 0)
{
StringBuilder.ThreadSafeCopy(value, this.m_ChunkChars, this.m_ChunkLength, num2);
this.m_ChunkLength = this.m_ChunkChars.Length;
}
int num3 = valueCount - num2;
this.ExpandByABlock(num3);
StringBuilder.ThreadSafeCopy(value + (IntPtr)num2, this.m_ChunkChars, 0, num3);
this.m_ChunkLength = num3;
}
return this;
}
若超過預設的capacity,則藉由以下ExpandByABlock擴展
private void ExpandByABlock(int minBlockCharCount)
{
if (minBlockCharCount + this.Length > this.m_MaxCapacity)
{
throw new ArgumentOutOfRangeException("requiredLength", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
}
int num = Math.Max(minBlockCharCount, Math.Min(this.Length, 8000));
this.m_ChunkPrevious = new StringBuilder(this);
this.m_ChunkOffset += this.m_ChunkLength;
this.m_ChunkLength = 0;
if (this.m_ChunkOffset + num < num)
{
this.m_ChunkChars = null;
throw new OutOfMemoryException();
}
this.m_ChunkChars = new char[num];
}
資料來源 :