rpyc.Service接收150kB对象需要10秒(本地主机,无局域网问题)

4 投票
1 回答
1679 浏览
提问于 2025-04-17 13:21

我正在构建一个很大的(序列化后大小为150kB)虚拟字典,并在上面运行一个快速且顺畅的虚拟函数。

但是,当我通过一个叫做rpyc.Service的方式来调用这个函数时,耗时变成了10秒(而不是0.0009秒),即使我的客户端和服务器在同一台机器上(这里没有局域网延迟的问题)。

你知道为什么我的150kB对象在同一台机器上从客户端传到服务器会花这么长时间吗?

还有,为什么即使输入对象还没有“准备好”,函数dummy.dummy()还是会被调用(如果准备好了,那么在两个测试案例中函数的耗时应该是一样的)?

下面是我的Python(3.2)代码。我测量了在调用dummy.dummy(d)时所花的时间。

  1. 案例1:客户端调用dummy.dummy;执行时间 = 0.0009秒
  2. 案例2:rpyc服务调用dummy.dummy;执行时间 = 10秒

mini_service.py

import rpyc
from rpyc.utils.server import ThreadedServer
import dummy

class miniService(rpyc.Service):
    def exposed_myfunc(self,d):
        #Test case 2: call dummy.dummy from the service
        dummy.dummy(d)

if __name__=='__main__':
    t = ThreadedServer(miniService,protocol_config = {"allow_public_attrs" : True}, port = 19865)
    t.start()

mini_client.py

import rpyc
import sys
import pickle
import dummy

def makedict(n):
    d={x:x for x in range(n)}
    return d

if __name__ == "__main__":
    d=makedict(20000)
    print(sys.getsizeof(d))             #result = 393356

#   output = open("C:\\rd\\non_mc_test_files\\mini.pkl",'wb') #117kB object for n=20k
#   pickle.dump(d,output)
#   output.close()

#RUN1 : dummy.dummy(d) out of rpyc takes 0.00099 seconds
#   dummy.dummy(d)

#RUN2 : dummy.dummy(d) via RPYC on localhost takes 9.346 seconds
    conn=rpyc.connect('localhost',19865,config={"allow_pickle":True})
    conn.root.myfunc(d)

    print('Done.')  

dummy.py

import time

def dummy(d):
    start_ = time.time()
    for key in d:
        d[key]=0
    print('Time spent in dummy in seconds: ' + str(time.time()-start_)) 

1 个回答

2

看起来性能下降是因为rpyc在客户端和服务器之间保持对象(通过引用传递)同步所做的工作。

我现在在我的应用程序中做的是对输入对象进行深拷贝,然后在这个拷贝上进行操作,这样就模拟了通过值传递的机制。

注意:进行深拷贝需要在协议配置参数中设置allow_picke=True

撰写回答