C#三种字符串拼接⽅法的效率对⽐
C#字符串拼接的⽅法常⽤的有:StringBuilder、+、string.Format、List<string>。使⽤情况不同,效率不同。
1.+的⽅式
string sql = "update tableName set int1=" + int1.ToString() + ",int2=" + int2.ToString() + ",int3=" + int3.ToString() + " where id=" + id.ToString();
编译器会优化为:
string sql = string.Concat(new string[] { "update tableName set int1=", int1.ToString(), ",int2=", int2.ToString(), ",int3=", int3.ToString(), " where id=",
id.ToString() });
下⾯是string.Concat的实现:
public static string Concat(params string[] values)
{
int totalLength = 0;
if (values == null)
{
throw new ArgumentNullException("values");
}
string[] strArray = new string[values.Length];
for (int i = 0; i < values.Length; i++)
{
string str = values[i];
strArray[i] = (str == null) ? Empty : str;
totalLength += strArray[i].Length;
if (totalLength < 0)
{
throw new OutOfMemoryException();
}
}
return ConcatArray(strArray, totalLength);
}
private static string ConcatArray(string[] values, int totalLength)
{
string dest = FastAllocateString(totalLength);
int destPos = 0;
for (int i = 0; i < values.Length; i++)
{
FillStringChecked(dest, destPos, values[i]);
destPos += values[i].Length;
}
return dest;
}
private static unsafe void FillStringChecked(string dest, int destPos, string src)
{
int length = src.Length;
if (length > (dest.Length - destPos))
{
throw new IndexOutOfRangeException();
}
fixed (char* chRef = &dest.m_firstChar)
{
字符串截取拼接不固定fixed (char* chRef2 = &src.m_firstChar)
{
wstrcpy(chRef + destPos, chRef2, length);
}
}
}
先计算⽬标字符串的长度,然后申请相应的空间,最后逐⼀复制,时间复杂度为o(n),常数为1。固定数量的字符串连接效率最⾼的是+。但是字符串的连+不要拆成多条语句,⽐如:
string sql = "update tableName set int1=";
sql += int1.ToString();
sql += ...
这样的代码,不会被优化为string.Concat,就变成了性能杀⼿,因为第i个字符串需要复制n-i次,时间复杂度就成了o(n^2)。
2.StringBuilder的⽅式
如果字符串的数量不固定,就⽤StringBuilder,⼀般情况下它使⽤2n的空间来保证o(n)的整体时间复杂度,常数项接近于2。
因为这个算法的实⽤与⾼效,类库⾥⾯有很多动态集合都采⽤这种牺牲空间换取时间的⽅式,⼀般来说效果还是不错的。
3.string.Format的⽅式
它的底层是StringBuilder,所以其效率与StringBuiler相似。
4.List<string>它可以转换为string[]后使⽤string.Concat或string.Join,很多时候效率⽐StringBuiler更⾼效。List与StringBuilder采⽤的是同样的动态集合算法,时间复杂度也是O(n),与StringBuilder不同的是:List的n是字符串的数量,复制的是字符串的引⽤;StringBuilder的n是字符串的长度,复制的数据。不同的特性决定的它们各⾃的适应环境,当⼦串⽐较⼤时建议使⽤List<string>,因为复制引⽤⽐复制数据划算。⽽当⼦串⽐较⼩,⽐如平均长度⼩于8,特别是⼀个⼀个的字符,建议使⽤StringBuilder。
--------------------------------------------------------------------------------
总结:
1>固定数量的字符串连接+的效率是最⾼的;
2>当字符串的数量不固定,并且⼦串的长度⼩于8,⽤StringBuiler的效率⾼些。
3>当字符串的数量不固定,并且⼦串的长度⼤于8,⽤List<string>的效率⾼些。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论