我有一个像这样的Base64编码字符串:
SWwgw6l0YWl0IHVuIHBldGl0IG5hdmlyZS [...] 0IG5hdmlyZSA=
输入字符串可以大(> 1MB)。出于互操作性的原因,我需要每64个字符将一个回车符添加到该大字符串中。
我的第一个猜测是使用stringbuilder并使用方法“AppendLine”每64个字符如下:
string InputB64_Without_CRLF = "SWwgw6l0YWl0IHVuIHBldGl0IG5hdmlyZS [...] 0IG5hdmlyZSA=";
int BufferSize = 64;
int Index = 0;
StringBuilder sb = new StringBuilder();
while (Index < strInput.Length) {
sb.AppendLine(InputB64_Without_CRLF.Substring(Index, BufferSize));
Index += BufferSize;
}
string Output_With_CRLF = sb.ToString();
但我担心这部分代码的性能。有没有更好的方法将字符插入某个位置的字符串而不重建另一个字符串?
答案 0 :(得分:5)
有没有更好的方法将字符插入某个位置的字符串而不重建另一个字符串?
.NET字符串是不可变的,这意味着一旦创建它们就无法修改它们。
因此,如果要将字符插入字符串,则但没有其他方法可以创建新字符。 StringBuilder
很可能是最有效的方法,因为它允许您根据需要执行尽可能多的字符串构建步骤,并且最后只创建一个新字符串。
除非您在实际场景中确实发现了性能问题,否则请保留当前的解决方案。它对我来说很好,至少从性能的角度来看。
需要考虑的其他一些要点:
如果您对解决方案仍然不满意,我只能想到一些可能使您当前的解决方案更有效的小事:
预先声明StringBuilder
所需的容量,以便不必调整其后备字符缓冲区的大小:
var additionalCharactersCount = Environment.NewLine.Length * (input.Length / 64);
var sb = new StringBuilder(capacity: input.Length + additionalCharactersCount);
首先将完整的输入字符串插入StringBuilder
,然后每64个字符重复.Insert(…, Environment.NewLine)
。
我不确定这是否会真正提高执行速度,但将摆脱由.Substring
引起的重复字符串创建。自己衡量一下它是否比你的解决方案更快。
答案 1 :(得分:2)
您的代码效率不高,尝试节省100毫秒或更少通常是不值得的。但是如果您担心,这是另一种稍微有效的方式来插入一个新行(有时是\ r \ n,而不仅仅是\ n)每64个字符
string Output_With_CRLF = InputB64_Without_CRLF;
//Start at last index so that our new line inserts do not move the text, making sure to input every 64th of the original string
//This looks stupid to divide and multiply again, but it works because it is integer division
StringBuilder sb = new StringBuilder(InputB64_Without_CRLF);
for (int i = (InputB64_Without_CRLF.Length / 64) * 64; i >= 64; i -= 64)
sb.Insert(i, Environment.NewLine);
这只会比原始代码更有效率,您可能不会注意到很多差异。
与stakx交谈后,我有了这个想法。通过使用StringBuilder,您不会反复创建多个字符串。 StringBuilder非常高效,可以在不创建更多对象的情况下处理其插入。