作者ntuleo (里歐)
看板Python
標題Re: [問題] python multiProcess效能很差?
時間Wed Apr 29 09:41:58 2015
經過大家的提醒,我修改了我的代碼如下
if __name__ == "__main__":
content = input_file(target).split("\n")
content = manager.list(content)
for files in source:
obj_grab.append((LogCatcher(files), content))
pool = Pool()
pool.map(transferConcat, obj_grab)
pool.close()
pool.join()
def concatMessage(logCatcher, content):
for key in logCatcher.dic_map:
regex = re.compile(key)
for j in range(len(content)):
for m in re.finditer(regex, content[j]):
content[j] += logCatcher.index + obj_grab.dic_map[key]
def transferConcat(args):
return concatMessage(*args)
結果變82秒....
人生已經如此的艱難...
請問這裡哪一步又做錯了呢?
------------------------------------------------------------------------
補充:obj_grab是一個list,裡面放不同file input產生的logCatcher
content是我要改的file,用manager()宣告是要讓不同process同時修改
※ 引述《ntuleo (里歐)》之銘言:
: 主要是參考segmentfault的這篇
: http://segmentfault.com/a/1190000000414339
: 看起來很有效,可是實際...
: if __name__ == "__name__":
: pool = Pool()
: content = pool.map(transferConcat, [(obj_grab, content)])[0]
: pool.close()
: pool.join()
: def concatMessage(obj_grab, content):
: for logCatcher in obj_grab:
: for key in logCatcher.dic_map:
: regex = re.compile(key)
: for j in range(len(content)):
: for m in re.finditer(regex, content[j]):
: content[j] += " " + logCatcher.index + " " + logCatcher.dic_map[key]
: return content
: def transferConcat(args):
: return concatMessage(*args)
: 以上是我的代碼(部分,只貼問題點),執行時間22秒
: 若單純執行method大概也是22秒...等於沒加速...
: 我試過調整pool的數量,沒什麼效果
: 請問要怎麼做才能真正體現mulitiProcess的效能呢?
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.221.50.98
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Python/M.1430271720.A.120.html
1F:→ ccwang002: 你可能要說明一下你的程式做了什麼,或者給個 sample 04/29 12:48
2F:→ ccwang002: 因為我不知道怎麼把你原本的 code 跟新版的對應 04/29 12:49
3F:推 CaptainH: 這code真是可怕…就算能動也一堆bug 04/29 12:59
4F:推 CaptainH: 所有的process都存取同一份 content,又在迴圈裡更改迭 04/29 13:01
5F:→ CaptainH: 代對象,太可怕了 04/29 13:01
※ 編輯: ntuleo (124.219.31.93), 04/29/2015 19:30:32
6F:→ ntuleo: 很可怕嗎XD multiprocess不都是這樣嗎? 04/29 19:31
7F:推 beatitude: 都已經在用multiprocessing了還不懂得避開副作用 高手 04/29 19:42
8F:→ ntuleo: 怎麼說呢? 可以指點我一下嗎? 我不是高手... 04/29 19:45
9F:推 LiloHuang: 你不應該嘗試去修改輸入的資料,除非是 Shared memory 04/29 20:01
10F:→ LiloHuang: 無論是 multiprocess 或者 multithread 的實作裡 04/29 20:02
11F:→ LiloHuang: 你得想辦法讓每個 process (或 thread) 各自跑各自的 04/29 20:02
12F:→ LiloHuang: 等到跑完之後,再將資料做合併,才是一個比較好的方式 04/29 20:03
13F:→ LiloHuang: 當然這個方法未必適用於你要解決的問題,只是一旦使用 04/29 20:03
14F:→ LiloHuang: Shared memory 之後,你就得進行 Synchronization 保護 04/29 20:04
15F:→ LiloHuang: 過度的 Synchronization 會造成 CPUs 浪費時間在競爭鎖 04/29 20:04
16F:→ LiloHuang: 舉個例子來說,假設輸入是 a-z 的字串,平行的轉成大寫 04/29 20:05
17F:→ LiloHuang: from multiprocessing.pool import ThreadPool 04/29 20:05
18F:→ LiloHuang: pool = ThreadPool() 04/29 20:05
19F:→ LiloHuang: print reduce(lambda x,y: x+y, pool.map( 04/29 20:05
20F:→ LiloHuang: lambda x:x.upper(), map(chr, range(97, 123)))) 04/29 20:05
21F:→ LiloHuang: 上述的範例內,輸入是一個 list (分別為 a-z 字元) 04/29 20:07
22F:→ LiloHuang: 輸出也是一個 list (已經轉成 A-Z),再用 reduce 合併 04/29 20:07
23F:→ LiloHuang: 這就是一個概念,想要平行處理就要讓 task 真正的平行 04/29 20:07
24F:→ LiloHuang: 然而上述的例子,由於並不是 CPU intensive 的計算 04/29 20:09
25F:→ LiloHuang: 開了 thread (或 process) 反而會比沒開來的慢 04/29 20:09
26F:→ LiloHuang: 我無法回答你的程式為何會如此慢,建議貼 GitHub Gist 04/29 20:10
27F:→ LiloHuang: 如果你能附上完整的程式碼,以及可重現問題的輸入資料 04/29 20:11
28F:→ LiloHuang: 相信其他板友會比較有機會能夠幫你找到問題的癥結點 04/29 20:12
29F:推 LiloHuang: pool.map(...) 的概念是有輸入跟輸出,要特別留意這點 04/29 20:16
30F:→ LiloHuang: 另外實務上,請盡量避免使用 ThreadPool,改用 Pool 04/29 20:17
31F:→ LiloHuang: 我只是為求簡便示範給你看,以免實際程式被 GIL 給拖慢 04/29 20:17