我有一個 65K 的 CSV 資料。我需要對每條 csv 行進行一些處理,最后生成一個字串。我必須在檔案中寫入/附加該字串。
偽代碼:
for row in csv_data:
processed_string = ...
file_pointer.write(processed_string '\n')
如何使此寫入操作并行運行,以便主處理操作不必包括寫入檔案所花費的時間?我嘗試使用批量寫入(存盤 n 行,然后同時寫入)。但是,如果您能建議我一些可以并行執行此操作的方法,那就太好了。謝謝!
編輯:一個 csv 檔案中有 65K 條記錄。我正在處理它,它會生成一個字串(多行大約 10-12)。我必須將其寫入檔案。對于 65K 記錄,每條記錄得到 10-15 行的結果。通常代碼需要 10 分鐘才能運行。但是添加此檔案操作會將時間增加到 2-3 分鐘。那么,如果我可以在不影響代碼執行的情況下并行執行呢?
這是代碼部分。
for i in range(len(queries)): # 65K runs
Logs.log_query(i, name, version)
# processed_results = Some processing ...
# Final Answer
s = final_results(name, version, processed_results) # Returns a multiline string
f.write(s '\n')
"""
EXAMPLE OUTPUT:
-----------------
[0] NAME: Adobe Acrobat Reader DC | VERSION: 21.005
FAISS RESULTS (with cutoff 0.63)
id name version eol_date extended_eol_date major_version minor_version score
1486469 Adobe Acrobat Reader DC 21.005.20054 07-04-2020 07-07-2020 21 005 0.966597
327901 Adobe Acrobat Reader DC 21.005.20048 07-04-2020 07-07-2020 21 005 0.961541
327904 Adobe Acrobat Reader DC 21.007.20095 07-04-2020 07-07-2020 21 007 0.960825
327905 Adobe Acrobat Reader DC 21.007.20099 07-04-2020 07-07-2020 21 007 0.960557
327902 Adobe Acrobat Reader DC 21.005.20060 07-04-2020 07-07-2020 21 005 0.958580
327900 Adobe Acrobat Reader DC 21.001.20145 07-04-2020 07-07-2020 21 001 0.956085
327903 Adobe Acrobat Reader DC 21.007.20091 07-04-2020 07-07-2020 21 007 0.954148
1486465 Adobe Acrobat Reader DC 20.006.20034 07-04-2020 07-07-2020 20 006 0.941820
1486459 Adobe Acrobat Reader DC 19.012.20035 07-04-2020 07-07-2020 19 012 0.928502
1486466 Adobe Acrobat Reader DC 20.012.20048 07-04-2020 07-07-2020 20 012 0.928366
1486458 Adobe Acrobat Reader DC 19.012.20034 07-04-2020 07-07-2020 19 012 0.925761
1486461 Adobe Acrobat Reader DC 19.021.20047 07-04-2020 07-07-2020 19 021 0.922519
1486463 Adobe Acrobat Reader DC 19.021.20049 07-04-2020 07-07-2020 19 021 0.919659
1486462 Adobe Acrobat Reader DC 19.021.20048 07-04-2020 07-07-2020 19 021 0.917590
1486464 Adobe Acrobat Reader DC 19.021.20061 07-04-2020 07-07-2020 19 021 0.912260
1486460 Adobe Acrobat Reader DC 19.012.20040 07-04-2020 07-07-2020 19 012 0.909160
1486457 Adobe Acrobat Reader DC 15.008.20082 07-04-2020 07-07-2020 15 008 0.902536
327899 Adobe Acrobat DC 21.007.20099 07-04-2020 07-07-2020 21 007 0.895940
1277732 Acrobat Reader DC (classic) 2015 07-07-2020 * 2015 NaN 0.875471
OPEN SEARCH RESULTS (with cutoff 13)
{ "score": 67.98198, "id": 327901, "name": Adobe Acrobat Reader DC, "version": 21.005.20048, "eol_date": 2020-04-07, "extended_eol_date": 2020-07-07 }
{ "score": 66.63623, "id": 327902, "name": Adobe Acrobat Reader DC, "version": 21.005.20060, "eol_date": 2020-04-07, "extended_eol_date": 2020-07-07 }
{ "score": 65.96028, "id": 1486469, "name": Adobe Acrobat Reader DC, "version": 21.005.20054, "eol_date": 2020-04-07, "extended_eol_date": 2020-07-07 }
FINAL ANSWER [OPENSEARCH]
{ "score": 67.98198, "id": 327901, "name": Adobe Acrobat Reader DC, "version": 21.005.20048, "eol_date": 2020-04-07, "extended_eol_date": 2020-07-07 }
----------------------------------------------------------------------------------------------------
"""
uj5u.com熱心網友回復:
問: “在 python 中回圈處理時并行寫入檔案......”
A :
坦率地說,檔案 I/O 不是您與性能相關的敵人。
“恕我直言,Python(自始至終)使用 GIL 鎖來避免任何級別的并發執行(實際上是重新序列化代碼執行流程以在任意數量的執行緒之間跳舞,借出大約 100 [ms ] 的代碼解釋時間到一個又一個,一個又一個,因此只會增加解釋器的開銷時間(并且在每一輪都破壞所有預取到 CPU 核心快取中......支付完整的記憶體 I/O每次下一次重新獲取的成本)。所以執行緒是 python 中的反模式(除了,我可以接受,用于網路(長)傳輸延遲屏蔽) – user3666197 44 分鐘前“
鑒于 CSV 中列出的 65k 檔案應該盡快得到處理,性能調整的編排是目標,檔案 I/O 只是其中一個可以忽略不計(并且設計良好的延遲屏蔽)部分(這并不意味著,我們不能再搞砸了(如果試圖以另一種破壞性能的 ANTI 模式來組織它),可以嗎?)
提示#1:如果以性能為目標,請避免并抵制使用任何容易實作的目標 SLOC
如果代碼以最便宜的迭代器子句開頭,
無論是模型for aRow in aCsvDataSET: ...
還是真實代碼for i in range( len( queries ) ): ...- 這些(除了眾所周知是 python 代碼解釋能力中非常緩慢的一部分,第二個甚至是 Py3 中的迭代器范圍()迭代器,甚至是 Py2 生態系統中的沉默 RAM 殺手)更大的范圍)在“結構化編程”傳播中看起來不錯,因為它們形成了代碼更深層次部分的符合語法的分離,但由于重復支付的間接成本累積,它會產生非常高的成本影響. 最后注入的需要“協調”無序并發檔案 I/O 操作,原則上根本沒有必要,如果做得聰明,如果這樣一個微不足道的 SLOC(以及類似糟糕的設計決策)是不利性能影響的一個例子正在使用。
更好的方法?
- a) 避免頂層(緩慢且開銷昂貴)回圈
- b) 將 65k 引數空間“拆分”為不比物理設備上存在的記憶體 I/O 通道多多少的塊(評分程序,我可以從發布的文本中猜到,是記憶體 I/O密集的,因為某些模型必須通過所有文本才能進行評分)
- c ) spawn
n_jobs-many process workers,它將joblib.Parallel( n_jobs = ... )( delayed( <_scoring_fun_> )( block_start, block_end, ...<_params_>... ) )運行scoring_fun(...)65k 長引數空間的這種分布式塊部分。 - d) 在計算了分數和相關輸出之后,每個作業行程可以并且應該將其自己的結果歸檔到其私有的、專有的、防止沖突的輸出檔案中
- e)完成所有部分塊部分的處理后,
main-Python 行程可以加入已經(剛剛-[同時]創建的、平滑且非阻塞的 O/S 緩沖/交錯流、真實硬體-存放)存盤的輸出,如果這樣的需求是......,
并且
finito - 我們完成了(知道沒有更快的方法來計算相同的任務塊,這些任務主要是令人尷尬的獨立,除了需要協調它們碰撞-免費,附加成本最低)。
如果有興趣調整真實系統的端到端處理性能,請從-map
開始,然后驗證物理記憶體 I/O 通道的數量,并可以嘗試使用 Python行程實體化、訂閱不足或過度-訂閱比物理記憶體-I/O-通道數低一點或高一點。如果實際處理有一些對我們隱藏的可屏蔽延遲,則可能有機會產生更多作業人員,直到端到端處理性能持續穩定增長,直到系統噪音隱藏任何此類進一步的性能調整效果lstopojoblib.Parallel()n_jobsn_jobs
獎勵部分 - 為什么不受管理的延遲源會扼殺性能
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/432694.html
標籤:python-3.x 多线程 表现 并行处理 文件写入
