对于一般用途,涉及StringBuilder类的解决方案最适合重复多字符字符串。它经过优化,可以处理简单的串联无法实现的大量字符串的组合,而手工连接将很难或不可能高效地进行。此处显示的StringBuilder解决方案使用O(N)迭代来完成,此固定比率与重复的次数成正比。
但是,对于大量重复,或必须从中挤出高效率的情况,一种更好的方法是执行类似于StringBuilder基本功能的操作,但要从目标而不是从原始字符串中产生其他副本,如下。
public static string Repeat_CharArray_LogN(this string str, int times)
{
int limit = (int)Math.Log(times, 2);
char[] buffer = new char[str.Length * times];
int width = str.Length;
Array.Copy(str.ToCharArray(), buffer, width);
for (int index = 0; index < limit; index++)
{
Array.Copy(buffer, 0, buffer, width, width);
width *= 2;
}
Array.Copy(buffer, 0, buffer, width, str.Length * times - width);
return new string(buffer);
}
这样,每次迭代都会使源/目标字符串的长度加倍,从而节省了每次通过原始字符串时重置计数器的开销,而无需平滑地读取并复制现在更长的字符串,这是现代处理器可以做的事情更有效率。
它使用以2为底的对数来查找需要将字符串长度加倍的次数,然后进行多次。由于现在要复制的其余部分小于要复制的总长度,因此它可以简单地复制已生成内容的子集。
我已经在使用StringBuilder时使用了Array.Copy()方法,因为将StringBuilder的内容复制到自身中会产生开销,每次迭代都会产生一个包含该内容的新字符串。Array.Copy()避免了这种情况,同时仍然以极高的效率运行。
该解决方案需要O(1 + log N)次迭代才能完成,该速率与重复次数成对数增加(重复次数增加一倍等于一个额外的迭代),与其他方法相比节省了大量资金,而其他方法则按比例增加。