Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python rpyc.Service需要10秒来接收150kB的对象(在本地主机上,没有LAN问题)_Python_Rpyc - Fatal编程技术网

Python rpyc.Service需要10秒来接收150kB的对象(在本地主机上,没有LAN问题)

Python rpyc.Service需要10秒来接收150kB的对象(在本地主机上,没有LAN问题),python,rpyc,Python,Rpyc,我正在构建一个大的(pickle时为150kB)虚拟字典,并在其上运行一个运行快速而平稳的虚拟函数 当通过rpyc.Service公开相同的功能时,所用的时间变为10秒(而不是0.0009秒),即使我的客户端和服务器位于同一台主机上(这里没有LAN延迟问题) 你知道为什么我的150kB对象从客户端到同一主机上的服务器要花这么长时间吗 为什么即使输入对象还不“可用”(如果可用,那么在两个测试用例中花在函数中的时间是相同的),也会调用函数dummy.dummy() 参见下面我的python(3.2)

我正在构建一个大的(pickle时为150kB)虚拟字典,并在其上运行一个运行快速而平稳的虚拟函数

当通过rpyc.Service公开相同的功能时,所用的时间变为10秒(而不是0.0009秒),即使我的客户端和服务器位于同一台主机上(这里没有LAN延迟问题)

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

为什么即使输入对象还不“可用”(如果可用,那么在两个测试用例中花在函数中的时间是相同的),也会调用函数
dummy.dummy()

参见下面我的python(3.2)代码。我测量在dummy.dummy(d)中花费的时间

  • 案例1:dummy.dummy被客户调用;执行时间=0.0009
  • 案例2:dummy.dummy称为rpyc服务;执行时间=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()
    
    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.')  
    
    mini_client.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()
    
    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_)) 
    

    性能损失似乎来自于rpyc在客户机和服务器之间保持对象(通过引用传递)同步的工作

    我现在在应用程序中所做的是对输入对象进行深度复制,然后处理该复制,从而模拟值传递机制


    注意:深度复制需要在协议配置参数中设置
    allow_picke=True

    您是否分析了访问单个密钥所用的时间(即
    d[key]=0所用的时间)?我相信rpyc会进行一些序列化,每次执行
    d[key]=0时都会发送一些消息,这显然会将所花费的时间增加数千倍[不是一个python字节码,而是序列化+与另一个进程通信+获得结果,这是一个非常慢的IO)。这一点很好。对于客户端,d[key]=0迭代10次需要0秒。对于服务,它平均需要0.002秒。这是否意味着对象的每次修改都与客户端同步?是的。
    0.002
    对于单个操作来说太多了。它必须是进程之间的IO。如果你想让事情更快,你应该避免在远程IO上进行微小操作对象。当我在服务器端接收对象,然后处理副本时,我现在正在执行copy.deepcopy。这样,rpyc就不必处理保持客户端和服务器之间同步引用的问题。问题已解决。注意:看起来需要allow_picke=True。