4

我有一个 python 脚本,当它自己运行时效果很好。基于硬编码的输入目录,它扫描所有 .mdb 文件并将其放入列表中,然后在 for 循环中遍历它们。每次迭代都涉及多个表限制、连接、查询等。

唯一的问题.. 在输入数据集上运行大约需要 36 小时,虽然在这种情况下这个脚本只会用于这个数据集,但我想提高性能,因为我经常编辑字段选择,要包括的结果, join 方法等。我想说这需要很长时间,因为我的脚本效率低下,但任何低效率都会很小,因为几乎所有处理时间都专用于地理处理器对象。

我在主脚本中的相关内容是:

indir = "D:\\basil\\input"
mdblist = createDeepMdbList(indir)
for infile in mdblist:
    processMdb(infile)

当按顺序执行时,它也可以完美地执行。

我尝试过使用并行 Python:

ppservers = ()
job_server = pp.Server(ppservers=ppservers)

inputs = tuple(mdblist)
functions = (preparePointLayer, prepareInterTable, jointInterToPoint,\
          prepareDataTable, exportElemTables, joinDatatoPoint, exportToShapefile)
modules = ("sys", "os", "arcgisscripting", "string", "time")

fn = pp.Template(job_server, processMdb, functions, modules)
jobs = [(input, fn.submit(input)) for input in inputs]

它成功创建了 8 个进程、8 个地理处理器对象……然后失败了。

我没有对内置的 Python 多线程工具进行广泛的试验,但希望得到一些指导,以简单地生成多达 8 个进程,通过 mdblist 表示的队列。任何时候都不会尝试同时由多个进程写入或读取任何文件。为了让事情暂时变得更简单,由于这个问题,我还删除了所有的日志工具;除了 4104 输入的 4 个文件的数据格式略有不同外,我已经运行了这个脚本足够多的时间来知道它可以工作。

建议?尝试多线程 Arc Python 脚本的智慧?

4

2 回答 2

5

以为我会分享最终对我有用的东西和我的经验。

根据 Joe 的评论,使用多处理模块 (code.google.com/p/python-multiprocessing) 的 backport 效果很好。我不得不在我的脚本中更改一些东西来处理本地/全局变量和日志记录。

主脚本现在是:

if __name__ == '__main__':

    indir = r'C:\basil\rs_Rock_and_Sediment\DVD_Data\testdir'
    mdblist = createDeepMdbList(indir)

    processes = 6  # set num procs to use here
    pool = multiprocessing.Pool(processes)

    pool.map(processMdb, mdblist)

使用 6 个进程,总时间从约 36 小时变为约 8 小时。

我遇到的一些问题是,通过使用单独的进程,它们处理不同的内存堆栈并完全取出全局变量。队列可以用于这个,但我没有实现这个,所以一切都只是在本地声明。

此外,由于 pool.map 只能接受一个参数,因此每次迭代都必须创建然后删除地理处理器对象,而不是能够创建 8 个 gp 并将可用的一个传递给每个迭代。每次迭代大约需要一分钟,因此创建它的几秒钟并不是什么大问题,但它加起来。我没有做过任何具体的测试,但这实际上可能是一个很好的做法,因为任何使用过 Arcgis 和 python 的人都会知道,随着地理处理器处于活动状态的时间越长,脚本的速度就会大大降低(例如,我的一个脚本被共同使用超载输入和时间估计完成的工人从运行 1 小时后的 50 小时到运行过夜后的 350 小时到运行 2 天后的 800 小时……它被取消并限制输入)。

希望这可以帮助其他希望多处理大量可迭代输入的人:)。下一步:递归、多处理追加!

于 2011-02-21T19:27:59.010 回答
-1

我在同一个函数中比较了上述方法。结果:

Starting pp with 1 workers
Time elapsed:  4.625 s

Starting pp with 2 workers
Time elapsed:  2.43700003624 s

Starting pp with 4 workers
Time elapsed:  2.42100000381 s

Starting pp with 8 workers
Time elapsed:  2.375 s

Starting pp with 16 workers
Time elapsed:  2.43799996376 s

Starting mul_pool with 1 p
Time elapsed:  5.31299996376 s

Starting mul_pool with 2
Time elapsed:  3.125 s

Starting mul_pool with 4
Time elapsed:  3.56200003624 s

Starting mul_pool with 8
Time elapsed:  4.5 s

Starting mul_pool with 16
Time elapsed:  5.92199993134 s
于 2011-05-30T02:55:05.827 回答