2011-12-01 72 views
5

我目前正在试用Actor-concurreny(在Python上),因为我想了解更多。所以我选择了pykka,但是当我测试的时候,它比多了一半,慢了作为一个正常的功能。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 

回答

12

那么,什么是这里发生的是你的功能版本正在创建两个非常大的列表,这是大部分时间。当你介绍演员时,必须复制像列表这样的可变数据,然后才能将发送给演员以保持适当的并发性。此外,演员内部创建的列表也必须复制以及发送回发件人。这意味着,不是创建两个非常大的列表,而是创建四个非常大的列表。

考虑设计一些东西,以便数据由演员构建和维护,然后通过对演员的调用来查询,从而最大限度地减少来回传递的消息的大小。尝试应用最小数据移动原理。在功能情况下传递List只是有效的,因为数据实际上并没有移动来利用共享内存空间。如果演员在不同的机器上,即使消息数据是不可变的,并且不需要复制,我们也不会享有共享内存空间的好处。

+0

我该如何提高效率?我从numpy阵列中创建了一个元组,但获得的并不是很高。 (例如:分发循环高效的服务角色。) – Themerius

+0

我更新了我的答案。基本上设计更具挑战性,但它具有更多的好处,比如在一组机器上执行。 –

+0

谢谢,我现在尝试构建一些东西。 – Themerius