Я работаю над кроссплатформенным приложением в PyQT 5.13 с Python 3.6 / 7. В начале мое приложение должно рекурсивно искать некоторые файлы, скажем, они представляют собой txts, в определенной пользователем группе корневых путей (так, потенциально, во всех дисках системы). Я подумал, что было бы неплохо использовать ThreadPoolExecutor
для распараллеливания сканирования из корневых папок, и в итоге я написал этот класс:
class StartupScanDispatcher(QThread):
scanComplete = pyqtSignal(dict)
@classmethod
def __scantree(cls, path: str) -> List[DirEntry]:
result: List[DirEntry] = []
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
try:
result.extend(cls.__scantree(entry.path))
except Exception as e:
print("EXCEPTION: {}".format(e))
else:
# Get entry extension
ext: str = os.path.splitext(entry.path)[1].lower()
# Filter entry based on it's extension
if ext == ".txt":
result.append(entry)
return result
def __init__(self, parent: QObject, paths: List[str]) -> None:
super(StartupScanDispatcher, self).__init__(parent)
self.__paths: List[str] = paths
def run(self) -> None:
# Not passing "max_workers", fallback to default amount that's <CPU_CORES> * 5
with ThreadPoolExecutor() as executor:
future2Path: Dict[Future, str] = {}
path2List: Dict[str, List[str]] = {}
for mPath in self.__paths:
future2Path[executor.submit(
StartupScanDispatcher.__scantree,
mPath
)] = mPath
for future in as_completed(future2Path):
path: str = future2Path[future]
try:
path2List[path] = future.result()
except Exception as e:
print("EXCEPTION: {}".format(e))
self.scanComplete.emit(path2List)
«Проблема» заключается в том, что при измерениивремя выполнения этого сценария в моих двух средах разработки (Windows 10 64-битная с одним SSD и 2 HDD; Ubuntu 18.10 с SSD) кажется примерно идентичным времени, затраченному на замену всего блока with ThreadPoolExecutor() as executor
этим простым циклом:
for mPath in self.__paths:
StartupScanDispatcher.__scantree(mPath.getPath())
Мне было интересно, как это возможно: я сделал несколько ошибок при написании кода? Неправильно использовать ThreadPoolExecutor
вместе с os.scandir
? Что мне не хватает? Спасибо всем заранее.