Как получить максимальную производительность от .NET StreamWriter в C#?

Каков рекомендуемый подход для достижения наилучшей производительности, когда нам нужно создавать текстовые файлы размером более 10 МБ?

В коде есть несколько разделов, которые нужно записывать в один файл. Это означает много строк текста.

Вариант №1 (Эта логика будет вызываться несколько раз):

  1. Создайте экземпляр StreamWriter
  2. Напишите несколько строк (в соответствии с некоторой бизнес-логикой)
  3. Закройте экземпляр StreamWriter

Вариант №2:

  1. Создайте StreamWriter в начале программы
  2. Напишите все строки из разных частей кода.
  3. Закройте StreamWriter в самом конце, когда больше ничего не нужно писать.

Вариант №3: Любой другой?

Помните, что выходной файл может быть больше 10 МБ.


person Community    schedule 13.08.2009    source источник


Ответы (4)


Удерживание одного модуля записи будет более эффективным, чем многократное его открытие и закрытие. Однако, если это важные данные, вы должны вызывать Flush() после каждой записи, чтобы убедиться, что они попадут на диск.

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

Вы уверены, что у вас действительно есть проблема с производительностью? 10 МБ - это довольно мало в наши дни ... на моем нетбуке для записи 10 МБ требуется всего одна или две секунды (и нет, это не твердотельный накопитель).

person Jon Skeet    schedule 13.08.2009

Используйте StringBuilder для объединения вашего текста и открывайте и записывайте в файл только один раз.

person Gregoire    schedule 13.08.2009
comment
Однако StringBuilder сохранит весь файл в памяти. - person David; 13.08.2009
comment
10мб памяти!? Это неслыханно! ;-) - person Sean Bright; 13.08.2009

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

Предполагая последовательный доступ, я бы никогда не пошел со сценарием 2. Он требует передачи вашего StreamWriter каждому разделу кода, который в нем нуждается. И кто ответит за то, что писатель снова закрылся. Это быстро станет непригодным для обслуживания.

Сценарий 1 имеет тот недостаток, что вы должны открывать StreamWriter везде, где он вам нужен, что также становится неудобным в сопровождении. Кроме того, теперь вы должны знать в каждом разделе кода расположение файла.

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

person Ronald Wildenberg    schedule 13.08.2009

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

person Community    schedule 13.08.2009