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

Python多进程共享内存性能低于pickling的原因及耗时检测问题

问题1:共享内存版本性能更差的核心原因
  • 额外的数据转换开销未被计入局部计时:你在main_shared里打印的done计时仅统计了pool.map的执行耗时,但整个函数内将原生Python列表转换为RawArray、最后再将RawArray转回Python列表的操作才是耗时大头,你提供的测试数据里pool.map仅耗时7.8s左右,剩下的30s总耗时全部来自这两次全量数据转换。
  • fork启动模式下原生多进程的开销本来更低:你使用的是fork启动方式,全局变量data会通过写时复制机制共享给子进程,只要子进程不修改原数据,根本不会触发额外的内存拷贝。而RawArray属于ctypes类型,无论读写都要经过Python对象和C类型的转换,访问开销远高于原生Python列表。
  • 共享内存版本多了两次全量拷贝:worker进程里你先将RawArray切片转成Python列表传给do_work,处理完又把结果列表写回RawArray,等于每个数据块多了两次全量拷贝,开销已经远超过常规多进程序列化返回结果的开销。
问题2:统计pickling/unpickling耗时的方法

直接调用pickle模块手动对目标数据做序列化/反序列化,叠加计时逻辑即可,示例代码如下:

import pickle, time

data, _ = setup()
test_block = data[0]

# 统计序列化耗时
start = time.time()
serialized = pickle.dumps(test_block)
serialize_cost = time.time() - start
print(f"单块序列化耗时: {serialize_cost:.4f}s")

# 统计反序列化耗时
start = time.time()
deserialized = pickle.loads(serialized)
deserialize_cost = time.time() - start
print(f"单块反序列化耗时: {deserialize_cost:.4f}s")

如果要统计整个程序生命周期内的pickle总开销,可以用cProfile运行脚本,查看pickle.dump/pickle.load相关函数的调用总耗时。

额外优化建议

你当前的场景不需要用共享内存,fork模式下的写时复制已经足够降低数据拷贝开销。如果要进一步提升性能,优先将do_work的纯Python循环改为numpy向量化操作,性能提升会远高于多进程调优的效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:24:07