pykka -- Actor 运行缓慢?
我现在正在尝试使用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
这里发生的事情是,你的函数版本创建了两个非常大的列表,这占用了大部分时间。当你引入了“演员”这个概念时,像列表这样的可变数据在发送给演员之前必须被复制,这样才能保持正确的并发性。此外,演员内部创建的列表在发送回给发送者时也必须被复制。这意味着,原本只创建两个非常大的列表,现在变成了四个非常大的列表。
考虑设计时让演员来构建和维护数据,然后通过调用演员来查询数据,这样可以减少来回传递的信息大小。尽量遵循最小数据移动的原则。在函数的情况下传递列表之所以高效,是因为数据实际上并没有移动,而是利用了共享内存空间。如果演员在另一台机器上,我们就无法享受共享内存的好处,即使消息数据是不可变的,也不需要复制。