对于一般使用,涉及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为底的对数来计算需要将字符串长度翻倍多少次,然后继续这样做多少次。由于要复制的剩余部分现在小于它要复制的总长度,因此它可以简单地复制它已经生成的内容的子集。
我使用了Array.Copy()方法,而不是使用StringBuilder,因为将StringBuilder的内容复制到自身中会在每次迭代中产生带有该内容的新字符串的开销。Array.Copy()避免了这种情况,同时仍然以极高的效率进行操作。
这个解决方案需要O(1 + log N)次迭代才能完成,这个速率随着重复次数的增加呈对数增长(重复次数加倍等于一次额外的迭代),这比其他方法节省了大量的时间,其他方法按比例增加。