Улучшите производительность чтения с диска (несколько файлов) с поточной обработкой

Я должен найти, что метод читает большое количество маленьких файлов (о 300k файлах) максимально быстро.

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

Затем я пытался использовать PInvoke с CreateFile/ReadFile и использовать FILE_FLAG_SEQUENTIAL_SCAN, но я не ценил изменений.

Я попробовал несколькими потоками (разделите большой набор на блоки и имейте каждый поток, читая его часть), и этот путь я смог улучшить скорость просто немного (даже 5% с каждым новым потоком до 4).

Какие-либо идеи о том, как найти самый эффективный способ сделать это?

1
задан pablo 24 April 2010 в 10:00
поделиться

3 ответа

Как сказал вам @djna, ваш диск, вероятно, способен обслуживать только один поток за раз, поэтому несколько потоков в вашей программе не помогут и могут даже усугубить ситуацию. Разница во времени выполнения для однопоточной версии вашего кода, кажется, намного превышает экономию времени за счет многопоточности. Другими словами, статистическая значимость очевидного улучшения времени выполнения равна 0.

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

Другой вариант - распределить файлы по локальным дискам в сетевых системах и заставить каждую систему работать с определенной частью файлов. Насколько легко вам это реализовать, но вы не говорите нам достаточно, чтобы мы могли дать хороший совет по этому поводу, так что подумайте об этом.

2
ответ дан 3 September 2019 в 01:03
поделиться

Я бы загрузил все файлы один раз, сохранив их как большой файл. Затем ваше приложение может загрузить только один файл и просканировать 300 КБ файлов только на те, которые были изменены (по размеру, дате изменения или удалению / добавлению), применяя эти изменения к большому файлу в памяти.

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

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

0
ответ дан 3 September 2019 в 01:03
поделиться

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

Не могли бы вы расположить их на твердотельном диске, а не на физическом?

Можете ли вы загрузить данные в базу данных по мере их поступления. Тогда ваш поиск будет производиться по (возможно, проиндексированной) базе данных?

0
ответ дан 3 September 2019 в 01:03
поделиться
Другие вопросы по тегам:

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