2017-09-10 66 views
0

我有一個迭代遍歷數組的循環。對於數組中的每一項,它都會調用一個函數來發出django-rest-framework請求。每個函數調用都獨立於其他函數。優化循環制作django-rest-framework請求

如果數組有25個項目,則目前需要30秒才能完成。我試圖讓總時間縮短到不到10秒。

DRF請求佔用了該函數花費的時間的一半。用多處理池替換for循環是否合理?如果是這樣,我該如何確保每個進程使用請求包通過單獨的連接發出請求?

我嘗試了更換:

for scenario_id in scenario_ids: 
    step_scenario_partial(scenario_id) 

有:

pool = Pool(processes=2) 
pool.map(step_scenario_partial, scenario_ids) 

其失敗,原因是OpenSSL.SSL.Error:[( 'SSL程序', 'ssl3_get_record',「解密失敗或壞記錄mac')]

根據this,錯誤是由於在多個進程中重複使用相同的SSL連接。

回答

1

您可以使用concurrent python模塊(docs),它可以執行並行任務。實施例方法,返回響應的對象的列表:

from concurrent import futures 

def execute_all(scenario_ids, num_workers=5): 
    ''' 
    Method to make parallel API calls 
    ''' 
    with futures.ThreadPoolExecutor(max_workers=num_workers) as executor: 
     return [result for result in executor.map(step_scenario_partial, scenario_ids)] 

ThreadPoolExecutor的使用線程池執行異步並行的呼叫。您可以嘗試num_workers的值(從5開始),以確保總執行時間爲< 10秒。

+0

由於線程從不同時執行,線程是否會避免由於重新使用相同的SSL連接而導致的錯誤? – softweave

+1

嘗試了你的建議。 cumtime降低到了8.3秒,沒有錯誤。 – softweave