并行目录遍历 python
parallel directory walk python
我需要从给定的根位置开始读取目录树中的每个文件。我想使用并行性尽快完成此操作。我有 48 个内核和 1 TB 内存,因此线程资源不是问题。我还需要记录读取的每个文件。
我考虑使用 joblib,但无法将 joblib 与 os.walk 结合使用。
我可以想到两个办法:
- 遍历树并将所有文件添加到队列或列表,并有一个工作线程池使文件出列 - 最佳负载平衡,由于初始遍历和队列开销可能需要更多时间
- 生成线程并将树的一部分静态分配给每个线程 - 低负载平衡,无初始遍历,根据某种哈希分配目录。
或者有更好的方法吗?
EDIT 存储性能不是问题。假设有一个无限快的存储可以处理无限数量的并行读取
编辑 删除了多节点情况以保持对并行目录遍历的关注
最简单的方法可能是使用 multiprocessing.Pool
来处理在主进程中执行的 os.walk
的结果输出。
这假定您要并行化的主要工作是对单个文件进行的任何处理,而不是递归扫描目录结构的工作。如果您的文件很小并且您不需要对其内容进行太多处理,则情况可能并非如此。我还假设 multiprocessing
为您处理的进程创建将能够在您的集群上正确分配负载(这可能是真的,也可能不是真的)。
import itertools
import multiprocessing
def worker(filename):
pass # do something here!
def main():
with multiprocessing.Pool(48) as Pool: # pool of 48 processes
walk = os.walk("some/path")
fn_gen = itertools.chain.from_iterable((os.path.join(root, file)
for file in files)
for root, dirs, files in walk)
results_of_work = pool.map(worker, fn_gen) # this does the parallel processing
以这种方式并行化工作完全有可能比仅在单个进程中完成工作要慢。这是因为共享文件系统下的硬盘上的 IO 可能是瓶颈,如果磁盘需要更频繁地查找而不是读取较长的线性数据部分,则尝试并行读取多个磁盘可能会使它们都变慢。即使 IO 快一点,进程之间的通信开销也会吃掉所有的收益。
我需要从给定的根位置开始读取目录树中的每个文件。我想使用并行性尽快完成此操作。我有 48 个内核和 1 TB 内存,因此线程资源不是问题。我还需要记录读取的每个文件。
我考虑使用 joblib,但无法将 joblib 与 os.walk 结合使用。
我可以想到两个办法:
- 遍历树并将所有文件添加到队列或列表,并有一个工作线程池使文件出列 - 最佳负载平衡,由于初始遍历和队列开销可能需要更多时间
- 生成线程并将树的一部分静态分配给每个线程 - 低负载平衡,无初始遍历,根据某种哈希分配目录。
或者有更好的方法吗?
EDIT 存储性能不是问题。假设有一个无限快的存储可以处理无限数量的并行读取
编辑 删除了多节点情况以保持对并行目录遍历的关注
最简单的方法可能是使用 multiprocessing.Pool
来处理在主进程中执行的 os.walk
的结果输出。
这假定您要并行化的主要工作是对单个文件进行的任何处理,而不是递归扫描目录结构的工作。如果您的文件很小并且您不需要对其内容进行太多处理,则情况可能并非如此。我还假设 multiprocessing
为您处理的进程创建将能够在您的集群上正确分配负载(这可能是真的,也可能不是真的)。
import itertools
import multiprocessing
def worker(filename):
pass # do something here!
def main():
with multiprocessing.Pool(48) as Pool: # pool of 48 processes
walk = os.walk("some/path")
fn_gen = itertools.chain.from_iterable((os.path.join(root, file)
for file in files)
for root, dirs, files in walk)
results_of_work = pool.map(worker, fn_gen) # this does the parallel processing
以这种方式并行化工作完全有可能比仅在单个进程中完成工作要慢。这是因为共享文件系统下的硬盘上的 IO 可能是瓶颈,如果磁盘需要更频繁地查找而不是读取较长的线性数据部分,则尝试并行读取多个磁盘可能会使它们都变慢。即使 IO 快一点,进程之间的通信开销也会吃掉所有的收益。