3

我有一个 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 是要转换成完整路径的序列号,directories 是要在其中查找的目录列表,exts 是要尝试的可能扩展名列表(没有前导点),directoryContents 是 None 或大(数百数以千计的条目) dict 映射目录中文件的序列号以搜索到它们的全名。我的想法是,要完成大量序列号,将所有可以找到的序列号放入字典中以便快速查找它们会更快,而不是为每个序列号进行系统调用。对于要完成的大量 SN,这值得制作 dict 的成本。

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

4

1 回答 1

3

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

于 2012-08-02T19:14:10.990 回答