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

为何Python中继承Process类的多进程运行速度慢于其他方式?

为什么继承Process类实现的进程比target方式运行慢?

我在学习多线程与多进程技术时做了个实验,发现继承Process类实现的进程运行速度远慢于直接用target参数创建进程的方式,实验代码和结果如下:

from time import time
from multiprocessing import Process


def count(n):
    while n > 0:
        n -= 1

t0 = time()
count(100_000_000)
count(100_000_000)
print(time() - t0)

pr1 = Process(target=count, args=(100_000_000,))
pr2 = Process(target=count, args=(100_000_000,))

t0 = time()
pr1.start(); pr2.start()
pr1.join(); pr2.join()
print(time() - t0)

class Proc(Process):
    def __init__(self, num):
        super().__init__()
        self.num = num
    
    def run(self):
        while self.num > 0:
            self.num -= 1

        
pro1 = Proc(100_000_000)
pro2 = Proc(100_000_000)

t0 = time()
pro1.start(); pro2.start()
pro1.join(); pro2.join()
print(time() - t0)

# 运行结果:
# casual time :  7.1526172161102295
# two processes time :  3.7792704105377197
# two extended processes time :  9.833416223526001

核心原因:实例属性 vs 局部变量的访问效率差异

问题出在循环内部的变量访问方式:

  • 在count函数中,n是局部变量,Python对局部变量的访问是直接通过栈帧索引获取,速度极快。
  • 而在继承Process的Proc.run方法中,每次循环都要访问self.num——这是实例属性,每次访问都需要经过Python的属性查找机制(调用__getattribute__),还要处理可能的属性拦截、继承链查找等逻辑,单次访问的开销虽然小,但在1亿次循环的放大下,整体耗时就会显著增加。

验证与修复

如果把run方法修改为先将实例属性赋值给局部变量,再进行循环,就能消除这个差异:

class Proc(Process):
    def __init__(self, num):
        super().__init__()
        self.num = num
    
    def run(self):
        # 将实例属性转为局部变量
        n = self.num
        while n > 0:
            n -= 1

修改后运行,耗时会和target方式的进程基本一致,因为此时循环中访问的是局部变量,效率和count函数完全相同。

补充说明

两种进程创建方式的启动开销差异极小,不会导致这么大的时间差。真正的元凶是循环内部的变量访问效率被循环次数放大了——1亿次的微小开销累加,最终形成了数秒的差距。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:46:05