3

私はPythonアプリケーションのサブルーチンを持っており、8文字のシリアル番号のリストを取得し、ディレクトリのセットで、可能な拡張子の範囲を持つそれらの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は完全なパスに変換するシリアル番号、directorysはそれを検索するディレクトリのリスト、extsは試行できる拡張機能のリスト(先頭のドットなし)、directoryContentsはNoneまたはlarge(数百)のいずれかです。何千ものエントリ)ディレクトリ内のファイルのシリアル番号をフルネームにマッピングするように指示します。私の考えでは、大量のシリアル番号のセットを完成させるには、見つかったすべてのシリアル番号を辞書に入れて、それぞれをシステムコールするよりも、すばやく検索できるようにする方が速いと思いました。多数のSNを完了するには、これは口述を行うコストに見合う価値があります。

そして、私が予測したように、directoryContentsが入力されると、はるかに高速になります。ただし、これはマルチプロセッシングを使用しない場合にのみ当てはまります。ユーザーがマルチプロセッシングモードを切り替えることを許可します。これは、directoryContentsがNoneの場合に予想されるより高速です。(つまり、os.path.existsでファイルの存在を確認してファイルを検索する場合)ただし、ファイルのdictを確認する場合、マルチプロセッシングでCompleteSNを呼び出すと、プールが非常に遅くなり、10SN/秒未満のオーダーになります。 。(マルチプロセッシングを使用しない場合の数千と比較して)何が起こっているかについての私の最も良い推測は、Pythonがプールワーカー間でデータを共有するために使用するメカニズム(そのうち8つあると思います)がそのような大きなdict構造で行き詰まっているということです。誰かが私がここで何が起こっているのかを学ぶのを手伝ってもらえますか?

4

1 に答える 1

3

一般に、複数のプロセス間でデータ構造を共有するべきではありません。同期のオーバーヘッドにより、パフォーマンスが低下することがよくあります。おそらく、ルックアップ dict の個々のコピーをプロセスごとに 1 つずつ作成できますか?

于 2012-08-02T19:14:10.990 に答える