对于一般用途,涉及 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) 次迭代才能完成,该速率随重复次数成对数增加(重复次数加倍等于一次额外的迭代),比其他方法,按比例增加。