2014-09-29 2 views
-1

У меня есть Base64 кодированные строки вроде этого:Вставьте возврат каретки каждые 64 символов строки

SWwgw6l0YWl0IHVuIHBldGl0IG5hdmlyZS [...] 0IG5hdmlyZSA= 

входной строки может большой большой (> 1 МБ). И по соображениям совместимости мне нужно добавить возврат каретки в эту большую строку каждые 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' –

+3

Это кажется разумным подходом ко мне. Вы измеряли проблему с производительностью? – Blorgbeard

+0

В основном меня беспокоило дублирование потока данных 1 МБ из одной строки в другую. Но поскольку строка .NET неизменна, мы не можем этого избежать. – Thordax

ответ

5

Есть ли лучшее средство для вставки символа в строку в определенной позиции без перестройки другой строки?

Строки .NET неизменяемы, а это значит, что они не могут быть изменены после их создания.

Поэтому, если вы хотите вставить символы в строку, нет другого способа , но, чтобы создать новый. И StringBuilder - это, пожалуй, самый эффективный способ сделать это, потому что он позволяет выполнять как можно больше шагов построения строк и создавать только одну новую строку в конце.

Если вы действительно не заметили проблемы с производительностью в реальном сценарии, держите свое текущее решение. Это выглядит хорошо для меня, по крайней мере, с точки зрения производительности.

некоторых дополнительных тонкостей, чтобы рассмотреть следующие вопросы:

Если вы все еще не довольны своим решением, я могу думать лишь несколько мелких вещей, которые могли бы сделать ваше текущее решение более эффективным:

  • Объявить StringBuilder s требуемая мощность до фронта, так что его поддержка символов буфера не должны быть изменения размеров:

    var additionalCharactersCount = Environment.NewLine.Length * (input.Length/64); 
    var sb = new StringBuilder(capacity: input.Length + additionalCharactersCount); 
    
  • Сначала введите полную строку ввода в StringBuilder, а затем повторно .Insert(…, Environment.NewLine) каждые 64 символа.

    Я совсем не уверен, действительно ли это улучшит скорость выполнения, но это будет избавиться от повторяющегося создания строки, вызванного .Substring. Измерьте сами ли это быстрее, чем ваше решение или нет.

+1

Lol, у нас была такая же мысль, я изменил свой пост, чтобы показать, что пару минут назад. :) –

2

Ваш код не является неэффективным, попытка сэкономить 100 мс или менее обычно не стоит усилий. Но если вы обеспокоены тем, вот еще немного более эффективный способ, чтобы вставить новую строку (которая иногда \ г \ п, а не только \ п) каждые 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 очень эффективен и будет обрабатывать свою вставку без создания большего количества объектов.

+1

Почему это должно быть более эффективным? Строки неизменяемы, и вставка будет создавать новую строку 1Mb + 1 байта для каждой вставленной новой строки. Я бы сказал, что он делает (используя StringBuilder) лучше, чем вы предлагаете. – ds27680

+0

@ ds27680 Я изменил свое решение. Предыдущий был только очень маленьким, более эффективным, потому что он не создавал дополнительный объект StringBuilder и в моем опыте вставка быстрее, чем sub string. –

Смежные вопросы