Вопрос:

Ускорение конкатенации строк в C #

c# .net string c#-4.0 concatenation

5920 просмотра

6 ответа

6967 Репутация автора

Возможный дубликат:
Какой метод конкатенации строк лучше всего использовать на C #?

Здравствуй,

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

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

Важно: синтаксис чтения содержимого файла неверен, просто нужно дать представление

string x;

while (var < File.Length)
{
  if (File.Content[var] == "A")
  {
       x += 1;    
  }
  else
  {
     x += 0;
  }
  var++;
}
Автор: Sudantha Источник Размещён: 29.05.2011 04:43

Ответы (6)


28 плюса

62511 Репутация автора

Решение

Используйте StringBuilderвместо конкатенации строк.

Объект StringBuilder поддерживает буфер для размещения конкатенации новых данных. Новые данные добавляются в конец буфера, если доступно пространство; в противном случае выделяется новый больший буфер, данные из исходного буфера копируются в новый буфер, затем новые данные добавляются в новый буфер.

Строка, напротив, является неизменной, каждый раз, когда вы объединяете, она создает новый объект и выбрасывает старые, что очень неэффективно.

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

Если взять ваш псевдокод, это будет выглядеть так:

StringBulder x = new StringBuilder(10000); // adjust capacity to your needs

while (var < File.Length)
{
   if(File.Content[var] == "A")
      x.Append("1"); // or AppendLine, or AppendFormat
   else
      x.Append("2");
}
Автор: Alex Aza Размещён: 29.05.2011 04:46

7 плюса

139482 Репутация автора

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

Автор: BrokenGlass Размещён: 29.05.2011 04:46

19 плюса

104547 Репутация автора

System.Text.StringBuilderэто тип, который вы хотите использовать для операций конкатенации строк в цикле. Это будет гораздо более эффективным. Используйте .Append(value)на объекте во время каждой итерации.

StringBuilder builder = new StringBuilder();

// and inside your loop 
{
    if (blah)
        builder.Append("1");
    else
        builder.Append("0");
}

string output = builder.ToString(); // use the final result
Автор: Anthony Pegram Размещён: 29.05.2011 04:46

6 плюса

2416 Репутация автора

Используйте StringBuilder.

var sb = new StringBuilder();
sb.Append("abc");
sb.Append("def");
var str = sb.ToString();
Автор: Will Размещён: 29.05.2011 04:47

7 плюса

339 Репутация автора

Используйте StringBuilder, строки неизменны в .net, что означает, что при любой конкатенации создается копия строки.

Использование класса StringBuilder (MSDN)

StringBuilder sb = new StringBuilder();
sb.Append("1") // like so
Автор: Matt Размещён: 29.05.2011 04:48

2 плюса

4294 Репутация автора

Когда вы читаете файл побайтно, это может занять слишком много времени. Я бы порекомендовал вам прочитать блок байтов (например, 1024 или 2048) в цикле. Затем в прочитанном блоке используйте регулярное выражение, соответствующее вашему персонажу, особенно если у вас очень большой файл.

Пример кода будет выглядеть примерно так:

private string GetFileData(string fileName, string matchChar)
{
    StringBuilder x = new StringBuilder();
    int blockCount = 2048;
    int offset = 0;
    string pattern = matchChar;
    int k = -1;
    using (var sr = new System.IO.FileStream(fileName, System.IO.FileMode.Open))
    {
       while ((sr.CanRead) && (k != 0))
       {
           byte[] bt = new byte[blockCount];
           k = sr.Read(bt, 0, blockCount);
           string so = System.Text.UTF8Encoding.UTF8.GetString(bt);
           var m = new System.Text.RegularExpressions.Regex(pattern).Matches(so);
           foreach (System.Text.RegularExpressions.Match item in m)
           {
               x.Append(item.Value);
           }
       }
    }
    return x.ToString();
}

Вы бы назвали это как

GetFileData(@"c:\matchtest.ono", "a");
Автор: DeveloperX Размещён: 29.05.2011 05:17
Вопросы из категории :
32x32