2014-09-29 70 views
-1

的我有Base64编码串是这样的:插入滑架每64个字符返回字符串

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

如果你正在使用'Convert.ToBase64String',您可以用'Base64FormattingOptions.InsertLineBreaks'参数 – 2014-09-29 19:37:31

+3

这似乎是一个合理的方法给我。你是否测量过性能问题? – Blorgbeard 2014-09-29 19:37:35

+0

我主要关心我的1MB数据流从一个字符串到另一个字符串的重复。但是由于.NET字符串是不可变的,我们无法避免这种情况。 – Thordax 2014-09-30 07:38:51

回答

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

大声笑,我们有同样的想法,我改变了我的帖子,只显示了几分钟前。 :) – 2014-09-29 20:06:44

2

你的代码效率不高,试图节省100ms或更少通常是不值得的。但是,如果你担心,这里是另一个插入新行会更有效的方式(这有时是\ 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); 

这只会更一点点比你原来的代码更高效,你可能不会注意到太多的区别。

与斯塔克斯交谈后,我有这个想法。通过使用StringBuilder,您不会一遍又一遍地创建很多字符串。 StringBuilder非常高效,并且会在不创建更多对象的情况下处理其插入。

+1

为什么这应该更有效率?字符串是不可变的,插入将为每个插入的换行建立一个新的1Mb + 1字节的字符串。我会说他在做什么(使用StringBuilder)比你提出的要好。 – ds27680 2014-09-29 20:01:25

+0

@ ds27680我改变了我的解决方案。前面的一个只是一个非常微小的效率,因为它没有创建额外的StringBuilder对象,而插入比我的经验中的子字符串更快。 – 2014-09-29 20:04:51