You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化50万+文件的文档计数程序?线程/多进程是否可行?

优化方案:50万+文件的文档统计提速

先修复原代码的基础问题

原代码存在几个拖慢速度且导致统计错误的问题:

  • 每次循环重复调用build_paths()生成目录列表,完全没必要
  • file_list未在每个站点目录遍历后清空,统计的是累计总数而非单个站点的数量
  • 用rglob('*.doc*')会匹配大量无关文件(比如.docm、.doc.bak),后续再过滤后缀做了无用功

先修正这些问题,单线程就能提升不少速度:

from pathlib import Path

def build_paths():
    """Build list of all site Uploaded Files dirs"""
    return list(Path(r"K:\BigDog").glob(r'*\Data\Files'))

def count_doc_files(doc_list):
    """Count doc and docx files for Live sites."""
    file_dict = {}
    target_dirs = build_paths()  # 只生成一次目录列表
    for dir_path in target_dirs:
        site = dir_path.parts[3]
        # 直接统计符合后缀的文件数量,无需收集所有文件名
        count = 0
        # 分别遍历两种后缀,避免匹配无关文件
        for suffix in doc_list:
            count += sum(1 for _ in dir_path.rglob(f"*{suffix}"))
        file_dict[site] = count
    return file_dict

doc_list = ['.doc', '.docx']
print(count_doc_files(doc_list))

并行提速:多线程是更优选择

遍历大量文件属于IO密集型任务,此时多线程比多进程更合适——多进程的进程切换开销远大于线程,而IO等待时Python的GIL会释放,线程可以充分利用空闲时间。

用concurrent.futures.ThreadPoolExecutor实现多线程并行,每个目录单独统计后汇总结果:

from pathlib import Path
from concurrent.futures import ThreadPoolExecutor

def build_paths():
    return list(Path(r"K:\BigDog").glob(r'*\Data\Files'))

def count_single_dir(dir_path, doc_list):
    """单个目录的文件统计逻辑"""
    site = dir_path.parts[3]
    count = 0
    for suffix in doc_list:
        count += sum(1 for _ in dir_path.rglob(f"*{suffix}"))
    return (site, count)

def count_doc_files_parallel(doc_list, max_workers=4):
    target_dirs = build_paths()
    file_dict = {}
    # 用线程池并行处理每个目录
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = [executor.submit(count_single_dir, dir_path, doc_list) for dir_path in target_dirs]
        # 收集所有结果
        for future in futures:
            site, count = future.result()
            file_dict[site] = count
    return file_dict

doc_list = ['.doc', '.docx']
print(count_doc_files_parallel(doc_list))

额外提速建议

  • 调整max_workers:不用设太大,Windows下4-8个线程足够,过多线程反而会因文件系统竞争拖慢速度
  • 关闭Windows Defender实时监控:本地磁盘的杀毒软件实时扫描会严重拖慢文件遍历速度
  • 用os.scandir()替代pathlib.rglob():底层的os.scandir()遍历速度更快,尤其是深度目录场景,可改写遍历逻辑进一步提速

内容的提问来源于stack exchange,提问作者FancyPantsFlower

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:12:39