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

Python逐行读取文件时多进程比单进程慢4000倍,问题出在哪?

嘿,我来帮你拆解下为什么多进程反而更慢,以及怎么搞定这个问题~

问题根源分析

你的多进程代码变慢的核心问题其实出在跨进程通信(IPC)的开销太大,完全抵消了并行处理的优势!你用Manager()创建的共享队列和列表,本质上是通过后台套接字在进程间同步数据——每往队列里塞一行、往共享列表里加一次结果,都要做序列化、跨进程传输、反序列化,还要处理锁来保证安全。而你的处理逻辑又特别简单(只是分割制表符),这种通信开销比你实际做的工作还重,自然比单进程慢,CPU也因为大部分时间在等通信而跑不满。

另外你的代码还有个小疏漏:没给工作进程发退出信号(也就是往队列里放None),导致子进程会一直卡在in_queue.get()那里,最后可能没法正常退出,但这不是性能差的主要原因。

优化方案

针对大文件的简单行处理,我们可以用multiprocessing.Pool来替代手动管理队列和共享列表,Pool内部的任务分发机制更高效,能减少很多不必要的通信开销。这里有两种更合适的方式:

方案一:用Pool.imap处理逐行数据

imap是迭代式的,适合处理大文件,它会自动把数据分块发送给子进程,减少进程间的通信次数:

from multiprocessing import Pool

def process_line(line):
    # 你的处理逻辑,这里是分割制表符
    return line.split("\t")

if __name__ == "__main__":
    num_workers = 4
    file_path = "your_large_file.txt"
    
    with Pool(num_workers) as pool:
        # 打开文件并逐行迭代,imap会自动分发任务
        results = pool.imap(process_line, open(file_path, 'rt', newline="\n"))
        # 把结果收集到列表里(如果需要排序的话)
        sorted_results = sorted(results)
    
    print(sorted_results)

方案二:分块读取文件(更适合超大型文件)

如果文件特别大,可以先把文件分成几个大的块,每个进程处理一块,进一步减少IPC的次数:

from multiprocessing import Pool
import os

def process_chunk(chunk):
    results = []
    for line in chunk.splitlines():
        results.append(line.split("\t"))
    return results

def split_file_into_chunks(file_path, chunk_size=1024*1024*100):  # 100MB每块
    chunks = []
    with open(file_path, 'rt', newline="\n") as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            # 确保块结尾是完整的一行,避免分割到行中间
            if not chunk.endswith("\n"):
                chunk += f.readline()
            chunks.append(chunk)
    return chunks

if __name__ == "__main__":
    num_workers = 4
    file_path = "your_large_file.txt"
    
    chunks = split_file_into_chunks(file_path)
    with Pool(num_workers) as pool:
        # 每个进程处理一个块
        chunk_results = pool.map(process_chunk, chunks)
        # 合并所有结果
        all_results = []
        for res in chunk_results:
            all_results.extend(res)
        sorted_results = sorted(all_results)
    
    print(sorted_results)
额外优化建议
  • 如果你不需要保留所有结果,而是可以边处理边输出,那就不要把所有结果都存在内存里,这样能节省内存,也避免最后排序的开销。
  • Mac系统下,Python的multiprocessing默认用spawn方式创建进程(而非Linux的fork),会有一点额外的启动开销,但核心问题还是IPC,上面的方案已经能解决。
  • 测试的时候可以先拿小文件验证逻辑,再跑大文件,避免浪费时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:28:36