[英]How can I parallelize a pipeline of generators/iterators in Python?
假設我有一些 Python 代碼,如下所示:
input = open("input.txt")
x = (process_line(line) for line in input)
y = (process_item(item) for item in x)
z = (generate_output_line(item) + "\n" for item in y)
output = open("output.txt", "w")
output.writelines(z)
此代碼從輸入文件中讀取每一行,通過幾個函數運行它,並將輸出寫入輸出文件。 現在我知道函數process_line
、 process_item
和generate_output_line
永遠不會相互干擾,我們假設輸入和輸出文件在不同的磁盤上,這樣讀取和寫入不會相互干擾。
但是 Python 可能對此一無所知。 我的理解是Python會讀取一行,依次應用每個函數,將結果寫入輸出,然后只有將第一行發送到輸出后才會讀取第二行,這樣第二行就不會進入直到第一個管道退出。 我是否正確理解該程序將如何運行? 如果這是它的工作方式,是否有任何簡單的方法可以使多行可以同時在管道中,以便程序並行讀取、寫入和處理每個步驟?
你不能真正並行讀取或寫入文件; 最終,這些將成為您的瓶頸。 你確定你的瓶頸是 CPU,而不是 I/O?
由於您的處理不包含任何依賴項(根據您的說法),因此使用Python 的 multiprocessing.Pool 類非常簡單。
有幾種方法可以編寫它,但更簡單的 wrt 調試是找到獨立的關鍵路徑(代碼中最慢的部分),我們將使其並行運行。 讓我們假設它是 process_item。
……事實上,就是這樣。 代碼:
import multiprocessing.Pool
p = multiprocessing.Pool() # use all available CPUs
input = open("input.txt")
x = (process_line(line) for line in input)
y = p.imap(process_item, x)
z = (generate_output_line(item) + "\n" for item in y)
output = open("output.txt", "w")
output.writelines(z)
我還沒有測試過,但這是基本思想。 池的 imap 方法確保以正確的順序返回結果。
有沒有什么簡單的方法可以使多條線路可以同時在管道中
我寫了一個庫來做到這一點: https : //github.com/michalc/threaded-buffered-pipeline ,它在一個單獨的線程中迭代每個迭代。
那是什么
input = open("input.txt")
x = (process_line(line) for line in input)
y = (process_item(item) for item in x)
z = (generate_output_line(item) + "\n" for item in y)
output = open("output.txt", "w")
output.writelines(z)
變成
from threaded_buffered_pipeline import buffered_pipeline
input = open("input.txt")
buffer_iterable = buffered_pipeline()
x = buffer_iterable((process_line(line) for line in input))
y = buffer_iterable((process_item(item) for item in x))
z = buffer_iterable((generate_output_line(item) + "\n" for item in y))
output = open("output.txt", "w")
output.writelines(z)
這增加了多少實際並行度取決於每個迭代中實際發生的事情,以及您擁有多少 CPU 內核/它們有多忙。
經典的例子是 Python GIL:如果每個步驟都相當占用 CPU,並且只使用 Python,那么不會添加太多並行性,並且這可能不會比串行版本快。 另一方面,如果每個網絡 IO 都很重,那么我認為它可能會更快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.