Подтвердить что ты не робот

Сделать конкатенацию строк быстрее в С#

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

Привет,

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

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

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

string x;

while (var < File.Length)
{
  if (File.Content[var] == "A")
  {
       x += 1;    
  }
  else
  {
     x += 0;
  }
  var++;
}
4b9b3361

Ответ 1

Используйте 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");
}

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

StringBuilder sb = new StringBuilder();
sb.Append("1") // like so

Ответ 5

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

var sb = new StringBuilder();
sb.Append("abc");
sb.Append("def");
var str = sb.ToString();

Ответ 6

Когда вы читаете байтовый файл байтом, это может занять слишком много времени. Я бы рекомендовал вам прочитать блок байтов (например, 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");