pykka -- Actor 运行缓慢?

7 投票
1 回答
3634 浏览
提问于 2025-04-17 07:27

我现在正在尝试使用Actor并发(在Python上),因为我想更多地了解这个概念。所以我选择了pykka,但在测试时发现它的速度比普通函数慢一半以上

这段代码只是用来看看它是否能工作,并不是为了追求优雅。:)

也许我哪里做错了?

from pykka.actor import ThreadingActor
import numpy as np

class Adder(ThreadingActor):
    def add_one(self, i):
        l = []
        for j in i:
            l.append(j+1)
        return l

if __name__ == '__main__':
    data = np.random.random(1000000)
    adder = Adder.start().proxy()
    adder.add_one(data)
    adder.stop()

这个运行得不太快:

time python actor.py

real    0m8.319s
user    0m8.185s
sys     0m0.140s

现在来看这个普通的“正常”函数:

def foo(i):
    l = []
    for j in i:
        l.append(j+1)
    return l

if __name__ == '__main__':
    data = np.random.random(1000000)
    foo(data)

得到这个结果:

real    0m3.665s
user    0m3.348s
sys     0m0.308s

1 个回答

14

这里发生的事情是,你的函数版本创建了两个非常大的列表,这占用了大部分时间。当你引入了“演员”这个概念时,像列表这样的可变数据在发送给演员之前必须被复制,这样才能保持正确的并发性。此外,演员内部创建的列表在发送回给发送者时也必须被复制。这意味着,原本只创建两个非常大的列表,现在变成了四个非常大的列表。

考虑设计时让演员来构建和维护数据,然后通过调用演员来查询数据,这样可以减少来回传递的信息大小。尽量遵循最小数据移动的原则。在函数的情况下传递列表之所以高效,是因为数据实际上并没有移动,而是利用了共享内存空间。如果演员在另一台机器上,我们就无法享受共享内存的好处,即使消息数据是不可变的,也不需要复制。

撰写回答