Чтение большого количества файлов быстро

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

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

7
задан Tim 8 July 2010 в 16:33
поделиться

3 ответа

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

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

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

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

7
ответ дан 7 December 2019 в 03:10
поделиться

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

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

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

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

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

0
ответ дан 7 December 2019 в 03:10
поделиться

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

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

2
ответ дан 7 December 2019 в 03:10
поделиться
Другие вопросы по тегам:

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