如何用Python多进程加速列表输入的重复函数执行以缩短耗时?
优化方案
一、先修复基础性能问题(立竿见影)
原代码里最拖慢速度的两个核心问题:
- 循环中反复调用
DataFrame.append():这个操作每次都会创建新的DataFrame对象,内存开销极大,数据量越大越慢。 - 冗余的索引遍历:用
range(len(check))再取check[i]完全没必要,直接遍历check元素更高效简洁。
修改后的基础版代码:
def sample_function(a,b,c): # 原函数逻辑 return A check = ['AA','BB','CC','DD'] q = 2 r = 3 # 先把所有结果收集到普通列表 results = [] for p in check: res = sample_function(p, q, r) results.append(res) # 最后一次性转换为DataFrame list_list = pd.DataFrame(results)
二、并行处理(针对CPU/IO密集型场景)
如果sample_function是CPU密集型(比如包含大量数值计算),优先用多进程;如果是IO密集型(比如调用外部接口、读写文件),用多线程更轻量。
1. 多进程实现(CPU密集型优先)
用concurrent.futures.ProcessPoolExecutor实现并行,代码示例:
import pandas as pd from concurrent.futures import ProcessPoolExecutor def sample_function(a,b,c): # 原函数逻辑 return A check = ['AA','BB','CC','DD'] q = 2 r = 3 # 启动进程池并行执行 with ProcessPoolExecutor() as executor: # 为每个check元素绑定固定参数q、r futures = [executor.submit(sample_function, p, q, r) for p in check] # 按顺序收集所有执行结果 results = [future.result() for future in futures] list_list = pd.DataFrame(results)
注意:如果sample_function依赖全局变量或不可序列化的对象,需要调整函数逻辑,确保参数能被pickle序列化(多进程间通信依赖pickle机制)。
2. 多线程实现(IO密集型优先)
把上面的ProcessPoolExecutor换成ThreadPoolExecutor即可,代码几乎完全一致:
from concurrent.futures import ThreadPoolExecutor # 其余代码同上 with ThreadPoolExecutor() as executor: futures = [executor.submit(sample_function, p, q, r) for p in check] results = [future.result() for future in futures] list_list = pd.DataFrame(results)
三、进阶:向量化改造(若可行)
如果sample_function的逻辑可以改造成支持批量输入(比如直接接受整个check列表作为参数,内部用numpy/pandas的向量化操作替代Python循环),速度提升会比并行更明显。示例:
def vectorized_sample_function(p_list, b, c): # 将原单元素处理逻辑改为批量处理 # 例如用numpy向量化运算、pandas Series操作替代Python循环 return pd.Series([process_single(p, b, c) for p in p_list]) # 此处为示例,需替换为真正的向量化逻辑 # 直接传入整个check列表执行 results = vectorized_sample_function(check, q, r) list_list = pd.DataFrame(results)
这种方式彻底避开了Python循环的开销,利用底层C实现的运算逻辑,性能提升最显著,但前提是函数逻辑能够被向量化改写。
内容的提问来源于stack exchange,提问作者Locco
相关产品推荐
相关产品推荐

