Производительность методов System.IO.ReadAllxxx / WriteAllxxx - PullRequest
2 голосов
/ 03 октября 2008

Имеется ли сравнение производительности методов System.IO.File.ReadAllxxx / WriteAllxxx с классами StreamReader / StremWriter, доступными в Интернете. Что, по вашему мнению, является лучшим способом (с точки зрения производительности) для чтения / записи текстовых файлов в .net 3.0?

Когда я проверял страницу MSDN класса System.IO.File , в примере кода MS использует StreamReader / StreamWriter для операций с файлами. Есть ли какая-то конкретная причина избегать методов File.ReadAllxxx / WriteAllxxx, даже если они выглядят намного проще для понимания?

Ответы [ 7 ]

5 голосов
/ 03 октября 2008

Возможно, вы не хотите использовать File.ReadAllxxx / WriteAllxxx, если у вас есть намерение поддержать загрузку / сохранение действительно больших файлов.

Другими словами, для редактора, который вы намереваетесь использовать при редактировании файлов размером гигабайт , вам нужен дизайн с StreamReader / StreamWriter и поиском, поэтому вы загружаете только часть файла виден.

Для всего, что не соответствует этим (редким) требованиям, я бы сказал, что выбираю простой маршрут и использую File.ReadAllxxx / WriteAllxxx. Они просто используют тот же шаблон StreamReader / Writer для внутреннего использования, который вы в любом случае будете кодировать вручную, как показывает aku.

4 голосов
/ 03 октября 2008

File.ReadAllText и аналогичные методы внутренне используют StreamReader / Writers, поэтому производительность должна быть сопоставима с тем, что вы делаете сами.

Я бы сказал, что по возможности используйте методы File.XXX, это делает ваш код а) более удобным для чтения; б) с меньшей вероятностью содержит ошибки (в любом случае, если вы пишете сами).

1 голос
/ 15 мая 2009

Эта MSR (Microsoft Research) статья является хорошим началом, они также документируют ряд точечных инструментов, таких как IOSpeed, FragDisk и т. Д., Которые вы можете использовать и тестировать в своей среде.

Существует также обновленный отчет / презентация, которую вы можете прочитать о том, как максимизировать последовательный ввод-вывод. Очень интересная вещь, так как они развенчивают, миф о том, что «перемещение головки HD - самая трудоемкая операция», они также полностью документируют свои тестовые окружения и связанные с ними конфигурации, вплоть до материнской платы, контроллера рейда и практически любой соответствующей информации, которую вы можете скопировать Работа. Некоторые из основных моментов - то, как Opteron / XEON совпали, но затем они также сравнили их с безумным \ Hype NEC Itanium (32 или 64 процессора или что-то) для измерения. Со второй ссылки здесь вы можете найти гораздо больше ресурсов о том, как тестировать и оценивать высокопроизводительные сценарии и потребности.

Некоторые другие статьи MSR в этой же теме исследования содержат рекомендации о том, где можно максимизировать свои расходы (например, ОЗУ, ЦП, дисковые шпиндели ... и т. Д.), Чтобы соответствовать вашим шаблонам использования ... все очень аккуратно.

Однако некоторые из них устарели, но, как правило, более старые API в любом случае являются более быстрыми / низкоуровневыми;)

В настоящее время я использую сотни тысяч TPS на специально созданном сервере приложений, используя смесь C #, C ++ / CLI, нативный код и кэширование растрового изображения (rtl * bitmap).

Береги себя;

1 голос
/ 03 октября 2008

Если вы не делаете что-либо, например, применяете регулярное выражение с многострочным соответствием к текстовому файлу, вам обычно нужно избегать ReadAll / WriteAll. Выполнение задач меньшими, более управляемыми частями почти всегда приводит к лучшей производительности.

Например, чтение таблицы из базы данных и отправка ее в веб-браузер клиента должны выполняться небольшими наборами, которые используют природу небольших сетевых сообщений и сокращают использование памяти компьютера обработки. Нет смысла буферизовать 10 000 записей в памяти на веб-сервере и выгрузить все сразу. То же самое касается файловых систем. Если вас беспокоит производительность записи многих небольших объемов данных - например, что происходит в базовой файловой системе для выделения пространства и какие накладные расходы - вы можете найти эти статьи поучительными:

Использование кэша файлов Windows

Тесты чтения файлов

Уточнение: если вы выполняете ReadAll, за которым следует String.Split ('\ r'), чтобы получить массив всех строк в файле, и использование цикла for для обработки каждой строки, код которой обычно будет приведет к худшей производительности, чем чтение файла построчно и выполнение вашего процесса в каждой строке. Это не жесткое правило - если у вас есть какая-то обработка, которая занимает много времени, часто лучше высвободить системные ресурсы (дескриптор файла) раньше, чем позже. Однако, что касается записи файлов, почти всегда лучше выгружать результаты любого преобразующего процесса (такого как вызов ToString () для большого списка элементов) для каждого элемента, чем буферизовать его в памяти.

0 голосов
/ 04 октября 2008

Эта ссылка имеет тесты для чтения строк 50 + K и указывает, что потоковая программа чтения примерно на 40% быстрее.

http://dotnetperls.com/Content/File-Handling.aspx

0 голосов
/ 03 октября 2008

Другие объяснили производительность, поэтому я не буду к ней прибавлять, однако добавлю, что вполне вероятно, что пример кода MSDN был написан до .NET 2.0, когда вспомогательные методы были недоступны.

0 голосов
/ 03 октября 2008

@ Фредрик Калсет прав. Методы File.ReadXXX являются просто удобными обертками для класса StreamReader.

Например, вот реализация File.ReadAllText

public static string ReadAllText(string path, Encoding encoding)
{
    using (StreamReader reader = new StreamReader(path, encoding))
    {
        return reader.ReadToEnd();
    }
}
...