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

Python多进程求列表最大值为何远慢于单进程?

多进程求列表最大值反而比单进程慢的问题分析与解决

问题背景

学习Python的multiprocessing模块时,编写了一个程序:先生成随机数列表,再分别用单进程和多进程两种方法查找列表中的最大值。但运行后发现,无论列表长度如何,多进程代码的运行速度总是比单进程慢数百倍。以下是两段尝试的代码:

第一段尝试代码

import random
import multiprocessing
import time

def random_num_list(length=100000):
     return [random.randint(-13443,435234) for i in range(length)]

rando_list = random_num_list()

def method1(lst):
    biggest_num = -13443
    for i in lst:
        if i > biggest_num:
            biggest_num = i

    return biggest_num

lst1, lst2 = rando_list[:int(len(rando_list)/3)], rando_list[int(len(rando_list)/3):]

def partial_process(lst1, lst2):
    biggest_num = -13443
    for i in lst1:
        if i > biggest_num:
            biggest_num = i

    lst2.append(biggest_num)
    #print("New record added!")

def full_process(lst2):
    biggest_num = -13443
    for i in lst2:
        if i > biggest_num:
            biggest_num = i

    print(biggest_num)

def method2(lst1,lst2):
    with multiprocessing.Manager() as manager:
        lst2 = manager.list(lst2)

        p1 = multiprocessing.Process(target=partial_process,args=(lst1, lst2))
        p2 = multiprocessing.Process(target=full_process,args=(lst2,))

        p1.start()
        p1.join()

        p2.start()
        p2.join()

if __name__ == '__main__':
    method2(lst1,lst2)
    print(method1(rando_list))

第二段尝试代码

def method2(lst):
    num_processes = multiprocessing.cpu_count()  # 进程数匹配CPU核心数
    chunk_size = len(lst) // num_processes

    with multiprocessing.Pool(processes=num_processes) as pool:
        # 拆分列表为多个块并行处理
        results = pool.map(find_max, [lst[i * chunk_size:(i + 1) * chunk_size] for i in range(num_processes)])

    return max(results)

问题原因分析

第一段代码的核心问题

  1. 完全没有并行执行:启动p1后立刻调用p1.join(),会等待p1完全结束才启动p2,两个进程是串行执行的,反而多了进程创建、销毁的开销。
  2. 共享内存对象开销极大:使用manager.list()创建跨进程共享列表,每一次append操作都需要进程间通信(IPC),这部分开销远大于计算本身。
  3. 逻辑冗余:partial_process把前1/3列表的最大值追加到后2/3列表中,再用full_process找最大值,其实和单进程直接找整体最大值的逻辑重复,完全没发挥多进程的并行计算优势。

第二段代码的潜在问题

  1. 缺少依赖函数:代码中未定义find_max函数,运行会报错。
  2. 进程开销抵消收益:如果列表长度太小(比如10万级),进程创建、列表分片、数据序列化/反序列化的开销,会远超过并行计算节省的时间。
  3. 进程数可能过多:cpu_count()返回的是逻辑核心数(比如8核16线程),开过多进程会导致CPU调度频繁切换,反而降低效率。

优化后的正确实现

以下是修复后的代码,加入计时功能,确保真正并行,并且使用足够大的列表来体现多进程优势:

import random
import multiprocessing
import time

def random_num_list(length=10**7):  # 增大列表到1000万条数据
    return [random.randint(-13443, 435234) for _ in range(length)]

# 单进程求最大值
def single_process_max(lst):
    max_val = lst[0]
    for num in lst[1:]:
        if num > max_val:
            max_val = num
    return max_val

# 子进程执行的求块最大值函数
def chunk_max(chunk):
    max_val = chunk[0]
    for num in chunk[1:]:
        if num > max_val:
            max_val = num
    return max_val

# 多进程求最大值
def multi_process_max(lst):
    num_processes = min(multiprocessing.cpu_count(), 4)  # 限制进程数为物理核心数或4,避免调度开销
    chunk_size = len(lst) // num_processes
    chunks = [lst[i*chunk_size : (i+1)*chunk_size] for i in range(num_processes)]
    # 处理最后一个块的剩余数据
    if len(lst) % num_processes != 0:
        chunks.append(lst[num_processes*chunk_size:])
    
    with multiprocessing.Pool(processes=num_processes) as pool:
        chunk_results = pool.map(chunk_max, chunks)
    
    return max(chunk_results)

if __name__ == '__main__':
    rando_list = random_num_list()
    
    # 测试单进程
    start_time = time.time()
    single_max = single_process_max(rando_list)
    single_time = time.time() - start_time
    print(f"单进程结果: {single_max}, 耗时: {single_time:.3f}秒")
    
    # 测试多进程
    start_time = time.time()
    multi_max = multi_process_max(rando_list)
    multi_time = time.time() - start_time
    print(f"多进程结果: {multi_max}, 耗时: {multi_time:.3f}秒")
    
    print(f"多进程比单进程快{single_time/multi_time:.2f}倍" if multi_time < single_time else "多进程未体现优势,请增大列表长度")

关键优化点

  1. 确保真正并行:使用Pool批量管理进程,自动分配任务,避免手动join导致的串行。
  2. 避免不必要的共享内存:直接传递列表分片给子进程,利用Python的复制-on-write机制减少数据拷贝开销,子进程计算完成后只返回单个最大值,而非共享列表。
  3. 控制进程数:限制进程数为物理核心数(而非逻辑核心数),避免过度调度。
  4. 使用足够大的计算量:只有当列表足够大(比如1000万条以上),并行计算的收益才会超过进程开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 07:00:21