作者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/cn.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