[英]How does the C# compiler work with a split?
我有一個List<string>
,我要對其進行迭代並拆分每個項目,然后將其添加到StringBuilder
。
foreach(string part in List)
{
StringBuilder.Append(part.Split(':')[1] + " ");
}
所以我的問題是通過此拆分創建了多少個字符串? 所有拆分將產生兩個項目。 所以...我在想它將創建一個string[2]
,然后創建一個空字符串。 但是,它是否隨后創建了string[1] + " "
的串聯,然后將其添加到StringBuilder
或進行了優化?
該代碼實際上等效於此:
foreach(string part in myList)
{
sb.Append(string.Concat(part.Split(':')[1], " "));
}
因此,是的,將創建一個附加string
,該string
代表拆分第二部分和空字符串的串聯。
包括原始string
在內,您還具有通過調用Split()
創建的兩個string
,以及對文字字符串" "
的引用,該字符串將從程序集元數據中加載。
您可以通過依次Append
分割結果和空字符串來保存對Concat()
的調用:
sb.Append(part.Split(':')[1]).Append(" ");
請注意,如果您僅使用字符串文字,那么編譯器將為您做出一種優化:
sb.Append("This is " + "one string");
實際上被編譯為
sb.Append("This is one string");
每個項目3個額外的字符串
part[0];
part[1];
part[1] + " "
最小的分配可能是完全避免所有臨時分配,但通常會進行微觀優化警告。
var start = part.IndexOf(':') + 1;
stringbuilder.Append(part, start, part.Length-start).Append(' ');
您有原始字符串'split'-1個字符串
您將“ split”拆分為兩個-2字符串
您已將拆分的兩個部分連接在一起-1個字符串
字符串構建器不會創建新的字符串。
當前代碼使用4個字符串,包括原始字符串。
如果要保存一個字符串,請執行以下操作:
StringBuilder.Append(part.Split(':')[1]);
StringBuilder.Append(" ");
這段代碼:
foreach(string part in List)
{
StringBuilder.Append(part.Split(':')[1] + " ");
}
等效於:
foreach(string part in List)
{
string tmp = string.Concat(part.Split(':')[1], " ");
StringBuilder.Append(tmp);
}
是的,它是不必要地創建字符串。 至少就生成的字符串數而言,這會更好:
foreach(string part in List)
{
StringBuilder.Append(part.Split(':')[1])
.Append(" ");
}
因此,對於列表中的每個值( n
,在代碼中稱為part
),您正在分配:
x
(我假設2個)字符串用於拆分。 n
用於連接的字符串。 StringBuilder
大約為n + 1
字符串; 可能要少得多。 因此,最后有nx + n + n + 1
,並假設分割總是產生兩個值4n + 1
。
改善此問題的一種方法是:
foreach(string part in List)
{
var val = part.Split(':')[1];
StringBuilder.EnsureCapacity(StringBuilder.Length + val.Length + 1);
StringBuilder.Append(val);
StringBuilder.Append(' ');
}
這使其成為3n + 1
。 這是一個粗略的估計,因為StringBuilder會在空間用完時分配字符串-但是,如果您EnsureCapacity
,則會防止其出錯 。
可能唯一可以確定如何編譯的方法是構建它,然后使用Refactor重新對其進行反編譯,以查看其內部處理方式。 無論如何,請記住,這可能不會影響整個應用程序的性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.