首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python管理器字典效率

Python管理器字典效率
EN

Stack Overflow用户
提问于 2014-07-01 23:57:52
回答 1查看 303关注 0票数 0

我有一个面向对象的Python程序,其中我使用多处理在每个对象中执行特定的数据操作。我将每个对象存储在一个通用的管理器字典中。当我想要更新一个对象时,首先,我从字典中检索对象,在更新之后,我将它放回原处。我的类结构如下

代码语言:javascript
复制
from src.data_element import Data_element
from multiprocessing import freeze_support, Process, Manager
import pandas as pd

class Data_Obj(Data_element):

    def __init__(self, dataset_name,name_wo_fields, fields):
        Data_element.__init__(self, dataset_name, name_wo_fields, fields)
        self.depends=['data_1','data_2'] 

    def calc(self,obj_dict_manager):
        data_1=obj_dict_manager['data_1']
        data_2=obj_dict_manager['data_2']

        self.df = pd.merge(
                          data_1.df, 
                          data_2.df, 
                             on='week', 
                             suffixes=('', '_y')
                           )[['week','val']]


def calculate(obj_dict_manager,data): 
     data_obj=obj_dict_manager[data]    
     data_obj.calc(obj_dict_manager)
     obj_dict_manager[data]=data_obj



if __name__ == '__main__':
    freeze_support()
    manager=Manager()
    obj_dict_manager=manager.dict() 
    obj_dict_manager=create_empty_objects(obj_dict_manager)

    joblist=[]
    for data in obj_dict_manager.keys():
        p=Process(target=calculate, args=(obj_dict_manager,data))
        joblist.append(p)
        p.start()
    for job in joblist:
        job.join() 

在这些操作期间,有大量的时间花费在

代码语言:javascript
复制
data_1=obj_dict_manager['data_1']
data_2=obj_dict_manager['data_2']

即,在从管理器字典中检索对象期间花费的1秒,而计算的其余部分又花费1秒。

有什么办法可以缩短我在这里花费的时间吗?我将进行数千次这样的操作,性能对我来说至关重要。

EN

回答 1

Stack Overflow用户

发布于 2014-07-17 04:39:35

重要的注意事项

您正在做一些具有潜在危险的事情:当您在obj_dict_manager中迭代键时,您将启动修改同一字典的进程。你永远不应该在迭代的时候修改某些东西,并且从子过程异步地进行修改可能会带来特别奇怪的结果。

问题的可能原因

1)我不知道您的共享字典中实际存储了多少对象(因为我们没有create_empty_objects()的代码),但如果数量很大,您的子进程可能会争用对共享字典的访问。特别是,由于您同时对字典进行读取和写入,因此它将在很多时候被一个或另一个进程锁定。

2)由于我们看不到您的共享字典中有多少key,我们也看不到有多少进程正在启动。如果您在系统上创建的进程比内核多,那么您的CPU可能会受到大量context switching的影响,这将使一切变慢。

3) #1和#2的组合-如果管理器将锁授予一个进程,然后该进程进入睡眠状态,这可能会特别有问题,因为在8核机器上,有几十个进程竞争CPU时间,现在每个人都必须等待,直到该进程唤醒并释放锁。

如何修复它

1)如果您的问题倾向于#1,请考虑拆分字典而不是使用共享字典,并将字典的一块传递给每个子进程,让它们执行所需的任何操作,让它们返回结果字典,然后在进程完成时重新组合所有返回的字典。如果你能把字典分成几部分,像multiprocessing.map_async()这样的东西可能更适合你。

2)在大多数情况下,尝试将产生的进程数量限制为系统上的核心数量,如果您的系统上同时运行了许多其他程序,则有时甚至更少。这种情况的一个例外是,如果你正在进行大量的并行处理,并且你预计子进程会被阻塞很多,比如在并行IO时。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24514656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档