Вы в невыгодном положении.
Проводник Windows почти наверняка использует FindFirstFile
/ FindNextFile
для обхода структуры каталогов и для сбора информации о размере (через lpFindFileData
) в один проход, делая, по сути, один системный вызов на файл.
В этом случае, к сожалению, Python не ваш друг. Таким образом,
os.walk
первые звонки os.listdir
(которые внутренне звонят FindFirstFile
/ FindNextFile
)
- любые дополнительные системные вызовы, сделанные с этого момента, могут сделать вас медленнее , чем Windows Explorer
os.walk
затем вызывает isdir
для каждого файла, возвращаемого os.listdir
(который внутренне вызывает GetFileAttributesEx
- или, до Win2k, GetFileAttributes
+ FindFirstFile
комбо), чтобы определить, рекурсировать или нет
os.walk
и os.listdir
будут выполнять дополнительное выделение памяти , операции со строками и массивами и т. Д., Чтобы заполнить их возвращаемое значение
- вы затем вызываете
getsize
для каждого файла, возвращаемого os.walk
(который снова вызывает GetFileAttributesEx
)
Это в 3 раза больше системных вызовов на файл, чем в Windows Explorer, плюс выделение памяти и накладные расходы на манипуляции.
Вы можете использовать решение Anurag или попытаться вызвать FindFirstFile
/ FindNextFile
напрямую и рекурсивно (что должно быть сопоставимо с производительностью cygwin
или другого порта win32 du -s some_directory
.)
Обратитесь к os.py
для реализации os.walk
, posixmodule.c
для реализации listdir
и win32_stat
(вызывается как isdir
и getsize
.)
Обратите внимание, что Python os.walk
неоптимален на всех платформах (Windows и * nices), вплоть до Python3.1. И в Windows, и в * nices os.walk
можно было пройти обход за один проход без вызова isdir
, так как FindFirst
/ FindNext
(Windows) и opendir
/ readdir
(* nix) уже возвращают тип файла через lpFindFileData->dwFileAttributes
(Windows) и dirent::d_type
(* nix).
Возможно, нелогично, в большинстве современных конфигураций (например, Win7 и NTFS и даже в некоторых реализациях SMB) GetFileAttributesEx
в в два раза медленнее, чем FindFirstFile
в одном файле (возможно, даже медленнее, чем итерация по каталог с FindNextFile
.)
Обновление: Python 3.5 включает новую функцию PEP 471 os.scandir()
, которая решает эту проблему, возвращая атрибуты файла вместе с именем файла. Эта новая функция используется для ускорения встроенного os.walk()
(как в Windows, так и в Linux). Вы можете использовать модуль scandir на PyPI , чтобы получить такое поведение для старых версий Python, включая 2.x.