【问题标题】:Python multiprocessing not increasing performancePython多处理不会提高性能
【发布时间】:2019-07-13 11:14:03
【问题描述】:

我写了一个简单的 python 多处理,它从 csv 读取一堆行,调用一个 api,然后写入新的 csv。但是,我看到的是该程序的性能与顺序执行相同。更改池大小没有任何效果。出了什么问题?

from multiprocessing import Pool
from random import randint
from time import sleep
import csv
import requests
import json



def orders_v4(order_number):



    response = requests.request("GET", url, headers=headers, params=querystring, verify=False)

    return response.json()


newcsvFile=open('gom_acr_status.csv', 'w')
writer = csv.writer(newcsvFile)

def process_line(row):
    ol_key = row['\ufeffORDER_LINE_KEY']
    order_number=row['ORDER_NUMBER']
    orders_json = orders_v4(order_number)
    oms_order_key = orders_json['oms_order_key']

    order_lines = orders_json["order_lines"]
    for order_line in order_lines:
        if ol_key==order_line['order_line_key']:
            print(order_number)
            print(ol_key)
            ftype = order_line['fulfillment_spec']['fulfillment_type']
            status_desc = order_line['statuses'][0]['status_description']
            print(ftype)
            print(status_desc)
            listrow = [ol_key, order_number, ftype, status_desc]
            #(writer)
            writer.writerow(listrow)
            newcsvFile.flush()


def get_next_line():
    with open("gom_acr.csv", 'r') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            yield row


f = get_next_line()

t = Pool(processes=50)

for i in f:

    t.map(process_line, (i,))

t.join()
t.close()

【问题讨论】:

  • 我认为您需要修改您的代码,以便能够执行以下操作:t.map(process_line, reader)。其中readerget_next_line 中的相同
  • 你应该在检查你的程序之前监控你的系统资源。如果您有 4 个核心以接近 100% 的速度运行,那么拥有更多进程几乎没有什么区别。当然,这只是一个例子。
  • 即使在您修复了map() 位置(循环外)之后 - 仍有很大的优化空间
  • 我使用results = t.map_async(process_line, (i,))results.get() 等待完成。现在程序非常快。

标签: python python-3.x python-multiprocessing


【解决方案1】:

编辑:我刚刚注意到您在循环中调用了map。你只需要调用一次。 is 是一个阻塞函数,它不是异步的!查看the docs 以获取正确用法示例。

map() 内置函数的并行等效项(尽管它仅支持一个可迭代参数)。 它会一直阻塞,直到结果准备好。

原答案:

所有进程都写入输出文件这一事实会导致文件系统争用。

如果您的 process_line 函数只返回行(例如,作为字符串列表),那么主进程将在 map 全部返回它们之后写入所有这些行,那么您应该会体验到性能提升。

另外,2 个注释:

  1. 尝试不同数量的进程,从 # of cores 开始并不断增加。也许 50 太多了。
  2. 每个流程中完成的工作似乎(在我看来,乍一看)相当短,可能是生成新流程和编排它们的开销太大而无法使手头的任务受益。

【讨论】:

  • 谢谢。 map_async 是一个答案。使用 map_async 使其在几秒钟内完成,而之前需要 5-10 分钟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 2012-12-15
  • 1970-01-01
相关资源
最近更新 更多