2

最近,我在我的php應用程序中遇到了一些嚴重的性能問題,它嘗試使用超過一萬行CSV數據做一些東西。 基本上我有大約十個函數,它由不同的preg_match/preg_replace動作組成,它處理解析後的csv-data(NLP DateParser,各種字符串修改事物,來自html源碼的圖像識別等)的每一行的一列。PHP + pthreads:構建一個大對象 - 並行處理

因爲我到達球體在腳本的處理是很慢(50秒和120秒之間),也爲內存問題(太複雜的對象),其現在是時候對一些性能改進;)

所以我就過來了pthreads允許在php腳本中進行多線程。但我不確定這是否對我的情況有幫助,或者只是產生比解決問題更多的性能問題(通過線程處理的開銷):

我的想法是遍歷所有一萬行,併爲每列啓動一個線程處理步驟(10k行+10列= 10k * 10 = 100.000個線程)。你認爲這會帶來性能改進嗎? 或者我應該寧願將csv-data分割成塊(可以說200行),它將在單獨的線程中處理(10k行/ 200塊= 50個線程)?

我會附上由我異形的PHP腳本的圖像,你可以看到哪些功能正在消耗大量的時間,但我遺憾的是沒有足夠的聲望值:/

是否有並行處理任何潛在的?我可以直接從不同的線程將屬性添加到同一個對象,還是必須先同步(因此等待線程完成)?是否有可能在多個線程中讀取同一個文件(線程1中的第一行,第二個線程中的第二個,等等),並在所有處理步驟結束時構建一個包含所有行的大對象?

我希望我的英語不好並不妨礙你理解我的想法和問題......

謝謝指教!

mfuesslin

編輯:我不知道的瓶頸:猜測最大的一個是處理所有CSV數據引起的大對象的處理...探查了我的注意一些多餘的foreach我可以省略的循環。 但主要問題是我必須處理的數據量。所有的處理功能不需要太多的時間(但是如果你連續處理10k ...)。

使用內存數據庫而不是csv操作的想法很好 - 會試一試。

preg_ *函數不能被str_ *函數替換,因爲我需要模式識別。

我也會嘗試Gearman,並嘗試將各個作業中的每個數據處理步驟分開。

PHP版本是5.6.10,啓用了opcache。

回答

2

聽起來像你想拔出一個真正的大槍。我不確定,pthreads將解決所有問題。我不會詳細討論如何應用pthreads,因爲這裏有很多事情要做,而且現有解決方案似乎還有一些改進空間。

  • 究竟哪裏是瓶頸?您是否對您的代碼進行了簡介並且在瓶頸上工作?
  • CSV
    • 也許你可以刪除它並將CSV數據導入到Db中?
    • 例如,如何使用SQLite內存中的Db進行處理
    • 您是否正在使用分塊解析來降低CSV解析器的內存佔用?
  • 您使用preg_*()功能:嘗試用字符串函數來替代它們
  • 分割你的數據處理功能,爲明確界定各個作業
  • 使用作業/隊列系統進行處理,像
  • 你的PHP呢?升級到5.6? opcache啓用?
+0

謝謝你的回答!我已經編輯了一些額外的信息我的帖子!肯定會嘗試Gearman! – mfuesslin

+0

很高興我能幫上一點忙。請考慮您可以在CLI上輕鬆導入CSV到數據庫,然後使用PHP中的數據庫。例如用Sqlite:'.mode csv' +'.import C:/work/data.csv table1';那會跳過你的PHP腳本的整個CSV分析步驟。 –