Я создаю метод в C#, который генерирует текстовый файл для Канала продукта Google. Канал будет содержать вверх 30 000 записей, и текстовый файл в настоящее время взвешивается в ~7Mb.
Вот код, который я в настоящее время использую (некоторые строки, удаленные для пользы краткости).
public static void GenerateTextFile(string filePath) {
var sb = new StringBuilder(1000);
sb.Append("availability").Append("\t");
sb.Append("condition").Append("\t");
sb.Append("description").Append("\t");
// repetitive code hidden for brevity ...
sb.Append(Environment.NewLine);
var items = inventoryRepo.GetItemsForSale();
foreach (var p in items) {
sb.Append("in stock").Append("\t");
sb.Append("used").Append("\t");
sb.Append(p.Description).Append("\t");
// repetitive code hidden for brevity ...
sb.AppendLine();
}
using (StreamWriter outfile = new StreamWriter(filePath)) {
result.Append("Writing text file to disk.").AppendLine();
outfile.Write(sb.ToString());
}
}
Я задаюсь вопросом, является ли StringBuilder правильным инструментом для задания. Было бы увеличение производительности, если бы я использовал TextWriter вместо этого?
Я не знаю тонну о производительности IO так никакая справка, или общие улучшения ценились бы.Спасибо.
Операции файлового ввода-вывода обычно хорошо оптимизированы в современных операционных системах. Не пытайтесь собрать всю строку для файла в памяти ... просто запишите ее по частям. FileStream
позаботится о буферизации и других аспектах производительности.
Вы можете легко внести это изменение, переместив:
using (StreamWriter outfile = new StreamWriter(filePath)) {
в начало функции и избавившись от записи StringBuilder
непосредственно в файл.
Есть несколько причин, по которым вам следует избегать создания больших строк в памяти:
StringBuilder
должен увеличивать свою емкость по мере того, как вы пишете в него, что приводит к перераспределению и копирование памяти. StringBuilder
в файл, вы должны использовать ToString ()
, что эффективно удваивает потребление памяти процессом, поскольку обе копии должны находиться в памяти в течение периода время. Эта операция также может завершиться неудачно, если ваше адресное пространство достаточно фрагментировано, так что нельзя выделить один непрерывный блок памяти. Просто переместите с помощью оператора
, чтобы он охватил весь ваш код, и напишите прямо в файл. Не вижу смысла сначала держать все это в памяти.
Записывать по одной строке, используя StreamWriter.Write, а не кэшировать все в StringBuilder.