Python中高效批量打开30万级TXT文件的优化方法咨询
优化大量小TXT文件处理效率的方案
针对你处理30万+小TXT文件的场景,当前单线程遍历+处理的方式效率太低,核心瓶颈在文件IO等待和可优化的代码细节,下面是几个实用的优化方向:
1. 多线程并行处理(核心优化)
小文件读取属于IO密集型任务,单线程会在等待文件读取时浪费CPU资源,用多线程可同时处理多个文件,大幅缩短总耗时。Python的concurrent.futures.ThreadPoolExecutor是最便捷的实现方式:
import os import re from concurrent.futures import ThreadPoolExecutor # 提前编译正则,避免每次循环重复编译 pattern = re.compile(r'\w+') def process_file(file_path): try: with open(file_path, 'r') as f: text = pattern.findall(f.read()) # 用for循环替代while,更高效简洁 for idx, token in enumerate(text): if token == "P1": function1(text) elif token == "T1": function2(text) except Exception as e: print(f"处理文件{file_path}出错: {e}") def main(): folder_path = "folder1" # 用os.scandir遍历,比os.listdir更快(减少额外系统调用) file_paths = [ os.path.join(folder_path, entry.name) for entry in os.scandir(folder_path) if entry.is_file() and entry.name.endswith('.txt') ] # 线程数可根据CPU核心数调整,一般设为核心数*2~4,或用max_workers=None自动适配 with ThreadPoolExecutor(max_workers=16) as executor: executor.map(process_file, file_paths) if __name__ == "__main__": main()
2. 优化文件遍历逻辑
os.scandir比os.listdir快30%-50%,因为它遍历过程中直接获取文件属性(如是否为文件),无需额外调用os.path.isfile,尤其适合大量文件的场景。
3. 代码细节优化
- 预编译正则:将
re.findall(r'\w+')改为提前编译的pattern.findall(),避免每次处理文件重复编译正则,节省重复开销。 - 替换while循环:用
enumerate遍历token,比手动维护index的while循环更高效、易读。 - 过滤无关文件:添加后缀判断,避免处理文件夹或非TXT文件。
4. 进阶优化(可选)
如果function1和function2是CPU密集型任务,可改用ProcessPoolExecutor(多进程),但注意多进程内存开销更大,仅适合CPU占用高的场景;若仍是IO密集,线程池足够。
内容的提问来源于stack exchange,提问作者Youssef Sabaa
相关产品推荐
相关产品推荐

