使用multiprocessing.Pool,Python例程运行速度要慢得多

时间:2012-08-02 18:51:46

标签: python multiprocessing

我有一个Python应用程序的子程序,它接受一个八字符序列号的列表,并在一组目录中搜索包含那些具有一系列可能扩展名的SN的文件名。执行此操作的功能如下。

def CompleteSN(SNorig, directories, exts, directoryContents=None):

    # Split SNorig into its directory path and basename
    directory, basename = os.path.split(SNorig)

    #Don't try to complete if it has a directory already
    if len(directory) > 0:
        return SNorig

    # Split the basename into extension (ext) and serial number (SN)
    SN = basename[:8].upper()

    #If we have a cache, check it
    if directoryContents is not None:
        if SN in directoryContents:
            return directoryContents[SN]
        else:
            return None

    possSNs = ['.'.join((SN, ext)) for ext in exts]

    for pSN in possSNs:
        for d in directories:
            dpath = os.path.join(d, pSN)
            if os.path.exists(dpath):
                return dpath

    return None

SN是转换为完整路径的序列号,目录是要查找的目录列表,exts是要尝试的可能扩展列表(没有前导点),而directoryContents是None或者大(数十万个条目)dict映射目录中文件的序列号以搜索其全名。我的想法是,要完成大量的序列号,将所有可以找到的序列号放入字典中会更快,因此可以快速查找它们而不是为每个序列号进行系统调用。要完成大量的SN,这将是制作字典的成本。

正如我预测的那样,一旦填充了directoryContents,它就会快得多。但是,仅在不使用多处理时才会出现这种情况。我允许用户切换多处理模式,当directoryContents为None时,该模式比预期更快。 (即当我们通过使用os.path.exists检查它们的存在来查找文件时)但是,当检查它们的dict时,在多处理中调用CompleteS.Pool非常慢,大约少于10个SN /秒。 (与不使用多处理时的数千个相比)我最好的猜测是,无论Python用于在池工作者之间共享数据的机制(其中我认为有8个)都被这么大的dict结构所困扰。谁能帮助我了解这里发生了什么?

1 个答案:

答案 0 :(得分:3)

通常,您不应在多个进程之间共享数据结构。同步开销通常会导致性能下降。也许您可以创建查找字典的单独副本,每个过程一个副本?