Я пробую к перечислению каталога ускорения в C++, где я рекурсивно вызываю в подкаталоги. У меня в настоящее время есть приложение, которое тратит 95% из, время в API FindFirst/FindNextFile, и требуется несколько минут для перечисления всех файлов на данном объеме. Я знаю, что возможно сделать это быстрее, потому что существует приложение, которое делает: Все. Это перечисляет мой весь диск в секундах.
Как я мог бы выполнить что-то вроде этого?
«Все» получает доступ к информации каталога на более низком уровне, чем API Win32 FindFirst / FindNext.
Я считаю, что он читает и интерпретирует структуры NTFS MFT напрямую, и что это одна из основных причин его производительности. Вот почему для этого требуются права администратора и почему «Все» индексирует только локальные или съемные тома NTFS (например, не сетевые диски).
Еще пара утилит, которые делают похожие вещи:
Небольшой реверс-инжиниринг с помощью отладчика этих инструментов может дать вам некоторое представление об используемых ими методах. использовать.
Не выполняйте recurse сразу, сохраните список найденных каталогов и погрузитесь в них, когда закончите. Вы хотите сделать линейный доступ к каждому каталогу, чтобы воспользоваться локальностью ссылок и любым кэшированием, которое делает ОС.
Если вы уже делаете все возможное, чтобы получить максимальную скорость от API, следующим шагом будет низкоуровневый доступ к диску и полный обход Windows. Вы можете получить некоторые инструкции из драйверов NTFS для Linux , или, возможно, вы можете использовать их напрямую.
«Все» строит индекс в фоновом режиме, поэтому запросы выполняются по индексу, а не к самой файловой системе.
Необходимо сделать несколько улучшений - по крайней мере, по сравнению с простым алгоритмом:
Во-первых, поиск по ширине превосходит поиск по глубине. То есть перечислите и обработайте все файлы в одной папке перед повторным переходом в найденные подпапки. Это улучшает местность - обычно значительно.
В Windows 7 / W2K8R2 вы можете использовать FindFirstFileEx
с FindExInfoBasic
, при этом основное ускорение заключается в пропуске короткого имени файла в файловых системах NTFS, где это разрешено.
Отдельные потоки помогают, если вы перечисляете разные физические диски (а не только диски). Для одного и того же диска это помогает, только если это SSD («нулевое время поиска») или вы тратите значительное время на обработку имени файла (по сравнению со временем, потраченным на доступ к диску).
[править] В Википедии действительно есть некоторые комментарии - {{1 }} По сути, они пропускают уровень абстракции файловой системы и напрямую обращаются к NTFS. Таким образом, они могут группировать вызовы и пропускать дорогостоящие службы файловой системы, такие как проверка ACL.
Хорошей отправной точкой может служить Технический справочник NTFS в MSDN.