Что самый быстрый путь к чтению-записи к диску в.NET?

Это должно быть столь же просто как:

SELECT UserId, Value
FROM Users u
WHERE Date = (SELECT MAX(Date) FROM Users WHERE UserID = u.UserID)
6
задан 5 July 2009 в 22:09
поделиться

4 ответа

Быстрый ввод-вывод файлов связан не столько с конкретными вызовами API, которые вы делаете, сколько с тем, как вы спроектируете свое приложение для работы с вводом-выводом.

Если вы выполняете все свои Операции ввода-вывода в одном потоке последовательно, например

  1. Считать блок в память
  2. Как-то обработать блок в памяти
  3. Записать блок в файл
  4. Повторять, пока не будет выполнено ...

вы ограничиваете пропускную способность системы ввода-вывода в цикле обработки одного потока. Альтернативный, но более сложный вариант - многопоточность вашего приложения для увеличения пропускной способности и избежания времени ожидания. Это позволяет системе одновременно использовать полосу пропускания ЦП и контроллера ввода-вывода. Типичный дизайн для этого будет выглядеть примерно так:

  1. Один (или несколько) рабочих потоков считывают данные с диска и добавляют их в общую очередь ввода.
  2. Один (или несколько) рабочих потоков читают блоки из общей очереди ввода, обрабатывают их и добавляют в общую очередь вывода
  3. Один (или несколько) рабочих потоков считывают обработанные данные, заблокированные из общей выходной очереди, и записывают их в соответствующие выходные файлы.

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

Если у вас действительно есть время и вы хотите выжать из системы максимум производительности, вы также можете использовать Порты завершения ввода-вывода - API относительно низкого уровня - для максимизации пропускной способности.

Удачи.

11
ответ дан 8 December 2019 в 13:01
поделиться

Вы профилировали свое приложение, чтобы определить, является ли дисковый ввод-вывод узким местом?

На каком типе оборудования вы это используете? Какова конфигурация оборудования?

В .NET вы можете попробовать пространство имен System.IO.File .

Для функций Win32 вы можете попробовать серии CreateFile, WriteFile, ReadFile.

пример:

http://msdn.microsoft.com/en-us/library/bb540534 (VS.85) .aspx

Это определенно не шаблонный вариант. Все дело в тестировании и измерении.

1
ответ дан 8 December 2019 в 13:01
поделиться

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

0
ответ дан 8 December 2019 в 13:01
поделиться

One возможность:

String imgRegex = "<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";

- это возможность (при совпадении без учета регистра). Это немного беспорядок и намеренно игнорирует случай, когда кавычки не используются. Чтобы представить его, не беспокоясь о побегах строк:

<img[^>]+src\s*=\s*['"]([^'"]+)['"][^>]*>

Это соответствует:

  • один или несколько символов, которые не являются > (т.е. возможные другие атрибуты)
  • src
  • необязательный пробел
  • =
  • необязательный пробел
  • начальный разделитель ' или "
  • источник изображения (который может не включать одинарные или двойные кавычки)
  • конечный разделитель
  • , хотя выражение можно здесь остановить, я добавил:
    • ноль или более символов, не являющихся > помощники, от первого лица их использования в ваших собственных приложениях, это факт что только ОДИН помощник класса для данного class может быть в области видимости в любое время ". ... "То есть, если у вас есть два помощника по объему будет признан только ОДИН компилятором. Вы не получите ничего предупреждения или даже намеки на любые другие вы можете сначала прочитать много файлов в буфер памяти одновременно (см. 2), а затем записать файлы на диск
    • Если исходный и целевой потоки расположены в разных местах (то есть не на одном жестком диске, возможно, в одном файл в сети, другой на локальном жестком диске и т. д.), вы можете использовать асинхронный шаблон для ускорения, читать данные с помощью BeginRead , а затем записывать данные с помощью BeginWrite , а пока данные записываются, прочтите следующий блок данных с помощью BeginRead.
    • Если вы все еще считаете, что производительности недостаточно (однако, согласно моему тесту, она сопоставима или даже быстрее, чем внутренняя копия Windows), вы можете использовать CopyFileEx Функция Win32 (но эта функция работает с файлами, а не потоками).
6
ответ дан 8 December 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: