看板 Python 關於我們 聯絡資訊
經過大家的提醒,我修改了我的代碼如下 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://www.ptt.cc/bbs/Python/M.1430271720.A.120.html
ccwang002: 你可能要說明一下你的程式做了什麼,或者給個 sample 04/29 12:48
ccwang002: 因為我不知道怎麼把你原本的 code 跟新版的對應 04/29 12:49
CaptainH: 這code真是可怕…就算能動也一堆bug 04/29 12:59
CaptainH: 所有的process都存取同一份 content,又在迴圈裡更改迭 04/29 13:01
CaptainH: 代對象,太可怕了 04/29 13:01
※ 編輯: ntuleo (124.219.31.93), 04/29/2015 19:30:32
ntuleo: 很可怕嗎XD multiprocess不都是這樣嗎? 04/29 19:31
beatitude: 都已經在用multiprocessing了還不懂得避開副作用 高手 04/29 19:42
ntuleo: 怎麼說呢? 可以指點我一下嗎? 我不是高手... 04/29 19:45
LiloHuang: 你不應該嘗試去修改輸入的資料,除非是 Shared memory 04/29 20:01
LiloHuang: 無論是 multiprocess 或者 multithread 的實作裡 04/29 20:02
LiloHuang: 你得想辦法讓每個 process (或 thread) 各自跑各自的 04/29 20:02
LiloHuang: 等到跑完之後,再將資料做合併,才是一個比較好的方式 04/29 20:03
LiloHuang: 當然這個方法未必適用於你要解決的問題,只是一旦使用 04/29 20:03
LiloHuang: Shared memory 之後,你就得進行 Synchronization 保護 04/29 20:04
LiloHuang: 過度的 Synchronization 會造成 CPUs 浪費時間在競爭鎖 04/29 20:04
LiloHuang: 舉個例子來說,假設輸入是 a-z 的字串,平行的轉成大寫 04/29 20:05
LiloHuang: from multiprocessing.pool import ThreadPool 04/29 20:05
LiloHuang: pool = ThreadPool() 04/29 20:05
LiloHuang: print reduce(lambda x,y: x+y, pool.map( 04/29 20:05
LiloHuang: lambda x:x.upper(), map(chr, range(97, 123)))) 04/29 20:05
LiloHuang: 上述的範例內,輸入是一個 list (分別為 a-z 字元) 04/29 20:07
LiloHuang: 輸出也是一個 list (已經轉成 A-Z),再用 reduce 合併 04/29 20:07
LiloHuang: 這就是一個概念,想要平行處理就要讓 task 真正的平行 04/29 20:07
LiloHuang: 然而上述的例子,由於並不是 CPU intensive 的計算 04/29 20:09
LiloHuang: 開了 thread (或 process) 反而會比沒開來的慢 04/29 20:09
LiloHuang: 我無法回答你的程式為何會如此慢,建議貼 GitHub Gist 04/29 20:10
LiloHuang: 如果你能附上完整的程式碼,以及可重現問題的輸入資料 04/29 20:11
LiloHuang: 相信其他板友會比較有機會能夠幫你找到問題的癥結點 04/29 20:12
LiloHuang: pool.map(...) 的概念是有輸入跟輸出,要特別留意這點 04/29 20:16
LiloHuang: 另外實務上,請盡量避免使用 ThreadPool,改用 Pool 04/29 20:17
LiloHuang: 我只是為求簡便示範給你看,以免實際程式被 GIL 給拖慢 04/29 20:17