Быстрое чтение большого количества файлов - PullRequest
7 голосов
/ 08 июля 2010

У меня есть большое количество (> 100 КБ) относительно небольших файлов (от 1 до 300 КБ), которые мне нужно прочитать и обработать.В настоящее время я перебираю все файлы и использую File.ReadAllText, чтобы прочитать содержимое, обработать его и затем прочитать следующий файл.Это довольно медленно, и мне было интересно, есть ли хороший способ оптимизировать его.

Я уже пытался использовать несколько потоков, но, поскольку это похоже на IO, я не увидел никаких улучшений.

Ответы [ 5 ]

7 голосов
/ 08 июля 2010

Скорее всего, вы правы - чтение того, что многие файлы, вероятно, ограничит ваше потенциальное ускорение, поскольку ограничением будет дисковый ввод-вывод.

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

Я бы порекомендовал попытаться создать единственную ветвь "продюсера", которая читает ваши файлы. Эта тема будет ограничена IO. Когда он читает файл, он может вставить «обработку» в поток ThreadPool (для этого тоже отлично подходят задачи .NET 4), чтобы выполнить обработку, которая позволила бы ему немедленно прочитать следующий файл.

Это, по крайней мере, отнимает «время обработки» из общего времени выполнения, делая общее время для вашей работы почти таким же быстрым, как у дискового ввода-вывода, если у вас есть дополнительное ядро ​​или два для работы с ...

2 голосов
/ 08 июля 2010

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

Во втором потоке попросите поток прочитать данные из этой очереди и обработать их.Посмотрите, поможет ли это!

0 голосов
/ 05 октября 2017

Я согласен с комментариями Рида и Icemanind.Кроме того, рассмотрим, как увеличить дисковый ввод-вывод.Например, разместите файлы на нескольких дисках, чтобы их можно было читать параллельно и использовать более быстрые диски, такие как SSD или, возможно, RAM-диск.

0 голосов
/ 02 ноября 2011

Я бы порекомендовал «MultiThreading» для решения этой проблемы. Когда я прочитал ваши посты ответы, вдруг обнаружил, что ответ Рида Копси будет таким продуктивным. Вы можете найти образец для этого решения, приготовленный Elmue по этой ссылке . Я надеюсь, что это может быть полезно и благодаря Риду Копси . Привет

0 голосов
/ 08 июля 2010

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

Если вы используете Windows, я бы переключился на использование NTFS (которая хранит небольшие файлы в записи каталога (-> сохранить один поиск диска на файл). Мы также используем сжатие дисков, (больше вычислений, но процессоры дешевы и быстры, но меньше места на диске -> меньше времени чтения); это может не иметь значения, если все ваши файлы маленькие. Может быть эквивалент файловой системы Linux, если вы там.

Да, вы должны запустить кучу потоков для чтения файлов:

     forall filename in list:   fork( open filename, process file, close filename)

Возможно, вам придется регулировать это, чтобы не допустить исчерпания потоков, но я бы стрелял сотнями, а не 2 или 3. Если вы сделаете это, вы скажете ОС, что она может читать множество мест на диске, и он может заказать несколько запросов путем размещения на диске ( алгоритм лифта ), и это также поможет минимизировать движение головы.

...