очень быстро получить общий размер папки

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

import os from os.path import join, getsize, isfile, isdir, splitext def GetFolderSize(path): TotalSize = 0 for item in os.walk(path): for file in item[2]: try: TotalSize = TotalSize + getsize(join(item[0], file)) except: print("error with file: " + join(item[0], file)) return TotalSize print(float(GetFolderSize("C:\\")) /1024 /1024 /1024) 

Это простой сценарий, который я написал, чтобы получить общий размер папки, это заняло около 60 секунд (+ -5 секунд). Используя многопроцессорную обработку, я получил ее до 23 секунд на четырехъядерном процессоре.

Использование проводника файлов Windows занимает всего ~ 3 секунды (щелкните правой кнопкой мыши-> свойства, чтобы убедиться сами). Итак, есть ли более быстрый способ найти общий размер папки, близкой к скорости, которую могут сделать окна?

Windows 7, python 2.6 (Прошли поиски, но большую часть времени люди использовали очень похожий метод для моего собственного). Спасибо заранее.

3 Solutions collect form web for “очень быстро получить общий размер папки”

Вы находитесь в невыгодном положении.

Проводник Windows почти наверняка использует FindFirstFile / FindNextFile как для прохождения структуры каталогов, так и для сбора информации о размере (через lpFindFileData ) за один проход, что делает по существу один системный вызов для каждого файла.

В этом случае Python, к сожалению, не ваш друг. Таким образом,

  1. os.walk сначала вызывает os.listdir (который внутренне вызывает FindFirstFile / FindNextFile )
    • любые дополнительные системные вызовы, сделанные с этого момента, могут только сделать вас медленнее, чем проводник Windows
  2. os.walk затем вызывает isdir для каждого файла, возвращаемого os.listdir (который внутренне вызывает GetFileAttributesEx – или, прежде чем Win2k, GetFileAttributes + FindFirstFile ), чтобы переопределить, следует ли повторять или нет
  3. os.walk и os.listdir будут выполнять дополнительное распределение памяти , операции с строками и массивами и т. д., чтобы заполнить их возвращаемое значение
  4. вы вызываете getsize для каждого файла, возвращаемого os.walk (который снова вызывает GetFileAttributesEx )

Это 3 раза больше системных вызовов на файл, чем в Проводнике Windows, а также на распределение памяти и накладные расходы.

Вы можете либо использовать решение Anurag, либо попытаться вызвать FindFirstFile / FindNextFile напрямую и рекурсивно (что должно быть сопоставимо с производительностью cygwin или другого win32-порта du -s some_directory .)

Обратитесь к os.py для реализации os.walk , posixmodule.c для реализации listdir и win32_stat (вызывается как isdir и getsize .)

Обратите внимание, что os.walk Python является субоптимальным на всех платформах (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 включает новую os.scandir() PEP 471 os.scandir() которая решает эту проблему, возвращая атрибуты файла вместе с именем файла. Эта новая функция используется для ускорения встроенного os.walk() (как для Windows, так и для Linux). Вы можете использовать модуль scandir на PyPI, чтобы получить это поведение для более старых версий Python, включая 2.x.

Если вам нужна такая же скорость, как и проводник, почему бы не использовать сценарии Windows для доступа к тем же функциям с помощью pythoncom, например

 import win32com.client as com folderPath = r"D:\Software\Downloads" fso = com.Dispatch("Scripting.FileSystemObject") folder = fso.GetFolder(folderPath) MB=1024*1024.0 print "%.2f MB"%(folder.Size/MB) 

Он будет работать так же, как и проводник, вы можете больше узнать о времени выполнения скриптов на странице http://msdn.microsoft.com/en-us/library/bstcxhf7(VS.85).aspx .

Я сравнивал производительность кода Python с деревом каталогов на 15 тыс., Содержащим файлы 190 тыс., И сравнивал его с командой du(1) которая, предположительно, происходит так же быстро, как и ОС. Код Python занял 3,3 секунды по сравнению с дю, который занял 0,8 секунды. Это было в Linux.

Я не уверен, что есть много, чтобы выжать из кода Python. Заметим также, что первый запуск du занял 45 секунд, что было очевидно, прежде чем соответствующие i-узлы были в кеше блока; поэтому эта производительность сильно зависит от того, насколько хорошо система управляет своим магазином. Меня это не удивило бы, если бы одно или оба:

  1. os.path.getsize является неоптимальным для Windows
  2. Windows подсчитывает размер содержимого каталога после вычисления
  • Python интерпретирует оптимизацию кода
  • Эффективный поиск словаря?
  • Когда не подходящее время для использования генераторов python?
  • Оптимизированный метод вычисления расстояния косинуса в Python
  • разделительный список в кусках сбалансированного веса
  • Как уменьшить использование памяти скрипта на Python
  • Улучшение дизайна кода дегазации выравнивания ДНК
  • Ускорение Python
  • Python - лучший язык программирования в мире.