如何在for循环中使用multiprocessing优化HTML解析拼接pandas dataframe任务
方案实现
你对技术选型的判断是正确的:HTML解析、结构化数据提取属于典型CPU密集型任务,受CPython*全局解释器锁(GIL)*限制,多线程无法利用多核CPU资源,multiprocessing(多进程)确实是最适配的方案。
前置优化点(串行场景也适用)
原有代码在循环中反复调用pd.concat会产生大量不必要的内存拷贝,性能损耗极大,优化逻辑为:先把所有解析结果存入列表,最后一次性合并即可。
多进程改造代码
我们直接用Python标准库concurrent.futures.ProcessPoolExecutor实现,语法更简洁,无需手动处理进程通信逻辑:
import glob import pandas as pd from concurrent.futures import ProcessPoolExecutor def get_clean_df(self): # 第一步:先收集所有待处理的文件路径 file_paths = glob.glob("../data/source/*/*.html") # 初始化结果存储列表 df_list = [] # 第二步:启动进程池批量处理 # max_workers默认等于CPU核心数,也可手动指定,建议不要超过CPU核心数的2倍 with ProcessPoolExecutor() as executor: # 映射所有文件路径到解析方法,返回的是按输入顺序排列的结果迭代器 for df in executor.map(self._extract_df_from_html, file_paths): df_list.append(df) # 第三步:一次性合并所有结果 result = pd.concat(df_list, ignore_index=True) return result
注意事项
- 如果运行时出现序列化(pickle)错误,通常是类实例方法
_extract_df_from_html不可被序列化导致的,可将该方法改为独立的顶层函数,把需要用到的类属性作为参数传入即可解决。 - 如果你的任务中文件读取IO占比很高,可以替换为
ThreadPoolExecutor做性能对比,IO密集场景下多线程开销更低,效果可能优于多进程。 - 进程数不要设置过高,否则进程调度、上下文切换的开销会抵消多核带来的性能收益。
内容的提问来源于stack exchange,提问作者user13450807
相关产品推荐
相关产品推荐

