加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python多处理Pool.map并不比调用函数一次快

发布时间:2020-12-20 13:42:14 所属栏目:Python 来源:网络整理
导读:我有一个非常大的字符串列表(最初来自文本文件),我需要使用 python进行处理.最终我试图采用map-reduce风格的并行处理. 我编写了一个“mapper”函数并将其提供给multiprocessing.Pool.map(),但它与使用完整数据集调用mapper函数所花费的时间相同.我一定做错了
我有一个非常大的字符串列表(最初来自文本文件),我需要使用 python进行处理.最终我试图采用map-reduce风格的并行处理.

我编写了一个“mapper”函数并将其提供给multiprocessing.Pool.map(),但它与使用完整数据集调用mapper函数所花费的时间相同.我一定做错了什么.

我尝试了多种方法,都有类似的结果.

def initial_map(lines):
    results = []
    for line in lines:
        processed = # process line (O^(1) operation)
        results.append(processed)
    return results

def chunks(l,n):
    for i in xrange(0,len(l),n):
        yield l[i:i+n]

if __name__ == "__main__":
    lines = list(open("../../log.txt",'r'))
    pool = Pool(processes=8)
    partitions = chunks(lines,len(lines)/8)
    results = pool.map(initial_map,partitions,1)

因此,块函数会生成一组原始行的子列表以提供给pool.map(),然后它应该将这8个子列表交给8个不同的进程并通过映射器函数运行它们.当我运行它时,我可以看到我的所有8个核心达到峰值100%.然而它需要22-24秒.

当我简单地运行它(单个进程/线程)时:

lines = list(open("../../log.txt",'r'))
results = initial_map(results)

它需要大约相同的时间. ~24秒.我只看到一个进程达到100%CPU.

我还尝试让池分割线本身,并使mapper函数一次只处理一行,结果相似.

def initial_map(line):
    processed = # process line (O^(1) operation)
    return processed

if __name__ == "__main__":
    lines = list(open("../../log.txt",'r'))
    pool = Pool(processes=8)
    pool.map(initial_map,lines)

~22秒.

为什么会这样?并行化这应该会导致更快的结果,不是吗?

解决方法

如果在一次迭代中完成的工作量非常小,那么您只需花费很大一部分时间与子进程进行通信,这是很昂贵的.相反,尝试将更大的数据片段传递给处理函数.类似于以下内容:

slices = (data[i:i+100] for i in range(0,len(data),100)

def process_slice(data):
    return [initial_data(x) for x in data]

pool.map(process_slice,slices)

# and then itertools.chain the output to flatten it

(没有我的补偿.所以不能给你一个完整的工作解决方案,也不能验证我所说的)

编辑:或者通过@ubomb查看问题的第3条评论.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读