我之前问了一个相关但非常普遍的问题(特别参见this response)。
这个问题非常具体。这是我关心的所有代码:
result = {}
for line in open('input.txt'):
key, value = parse(line)
result[key] = value
函数parse
完全是自包含的(即不使用任何共享资源)。
我有Intel i7-920 CPU(4核,8个线程;我认为线程更相关,但我不确定)。
如何让我的程序使用该CPU的所有并行功能?
我假设我可以打开此文件以便在8个不同的线程中读取,而不会造成太多性能损失,因为磁盘访问时间相对于总时间而言很小。
答案 0 :(得分:18)
cPython不提供您正在寻找的线程模型。您可以使用multiprocessing
模块和process pool
这样的解决方案看起来像这样:
def worker(lines):
"""Make a dict out of the parsed, supplied lines"""
result = {}
for line in lines.split('\n'):
k, v = parse(line)
result[k] = v
return result
if __name__ == '__main__':
# configurable options. different values may work better.
numthreads = 8
numlines = 100
lines = open('input.txt').readlines()
# create the process pool
pool = multiprocessing.Pool(processes=numthreads)
# map the list of lines into a list of result dicts
result_list = pool.map(worker,
(lines[line:line+numlines] for line in xrange(0,len(lines),numlines) ) )
# reduce the result dicts into a single dict
result = {}
map(result.update, result_list)
答案 1 :(得分:8)
为什么这是最好的方式...
答案 2 :(得分:3)
这可以使用Ray完成,Ray documentation是一个用于编写并行和分布式Python的库。
要运行下面的代码,请首先如下创建input.txt
。
printf "1\n2\n3\n4\n5\n6\n" > input.txt
然后,您可以通过向@ray.remote
函数添加parse
装饰器并按如下所示并行执行许多副本来并行处理文件
import ray
import time
ray.init()
@ray.remote
def parse(line):
time.sleep(1)
return 'key' + str(line), 'value'
# Submit all of the "parse" tasks in parallel and wait for the results.
keys_and_values = ray.get([parse.remote(line) for line in open('input.txt')])
# Create a dictionary out of the results.
result = dict(keys_and_values)
请注意,执行此操作的最佳方法取决于运行parse
函数所花费的时间。如果需要一秒钟(如上所述),则每个Ray任务解析一行是有意义的。如果需要1毫秒,则可能有必要解析每个Ray任务的一行代码(例如100条)。
您的脚本很简单,因此也可以使用多处理模块,但是,一旦您想做更复杂的事情或想利用多台计算机而不是一台计算机,那么使用Ray就会容易得多。 / p>
答案 3 :(得分:0)
您可以使用multiprocessing
模块,但如果parse()很快,那么这样做不会带来太多的性能提升。
答案 4 :(得分:0)
正如TokenMacGuy所说,您可以使用multiprocessing
模块。如果您确实需要解析大量数据,请查看 disco project 。
Disco 是一种分布式计算 基于MapReduce的框架 范例。迪斯科是开源的; 由诺基亚研究中心开发 解决处理中的实际问题 大量数据。
它真正适用于你的parse()作业是“纯粹”(即不使用任何共享资源)并且是CPU密集型的作业。我在一个核心上测试了一个作业,然后比较了在3个主机上运行它,每个主机有8个核心。在Disco群集上运行时,它实际上运行快了24倍(注意:测试了一个不合理的CPU密集型作业)。
答案 5 :(得分:0)
$ python makelist.py | parallel -j+2 'wget "{}" -O - | python parse.py'或者这种风格
$ ls *.wav | xargs -n1 --max-procs=4 -I {} lame {} -o {}.mp3
无论如何,你需要实现map / reduce范例