这个场景下,怎么提升python并行处理能力?

extend 2017-11-15 10:42:55
统计一个800多兆的日志文件有多少行,两个算法,一个单线程,一个并行,但是并行的效率远远低于单线程的算法,怎么提升并行算法的效率呢?
高手帮忙分析下。
单线程的算法和结果如下:
start_t=time.clock()

def block(file,size=65536):
while 1:
nb=file.read(size)
if not nb:
break
yield nb

with open("D:\Centos7\catalina.out","r",encoding="UTF-8") as f:
#print(type(f))
print(sum(line.count("\n") for line in block(f)))
#print(block(f))
print(time.clock()-start_t)

D:\new\Python\excersise>python test4.py
404325
4.501643689510964
效率4秒多。

并行算法和结果如下:
D:\new\Python\excersise>python test4.py
404325 11.875990500941482

def run(fn):
#print(sum(line.count() for line in fn))
#print(type(fn))
#print(fn)

return len(fn)

if __name__=="__main__":
start_t=time.clock()
sum1=0
fp=open("D:\Centos7\catalina.out","r",encoding="UTF-8")
ff=[]
while 1:
fb=fp.readlines(1048576) #65536(字节)*16*10,64kb*16=1024KB=1MB,
if not fb:
break
ff.append(fb)
fp.close()
#print(ff)
pool=mp.Pool(16)
#pool.map(run,ff)
sum_t=reduce(lambda x,y:x+y,pool.map(run,ff))
pool.close()
pool.join()
print(sum_t,time.clock()-start_t)
D:\new\Python\excersise>python test4.py
404325 11.875990500941482
结果12秒,无论调整并行度4,8,16,结果都差不多。
怎么提升并行效率呢?
...全文
201 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
extend 2017-11-15
  • 打赏
  • 举报
回复
引用 1 楼 oyljerry 的回复:

with open('filename') as file:
    for line in file:
        do_things(line)
多谢版主,你给的写法实际就是我上面的第一种单线程写法,我运行了下,两者执行时间也基本一致。 但我的问题是,多进程并行为啥慢那么多呢?是我上面多进程并行代码写的不够优化,算法不对?还是在这种场景下,多并行本来就比不过单线程?还是数据量不够大,多进程体现不出优势?
oyljerry 2017-11-15
  • 打赏
  • 举报
回复

with open('filename') as file:
    for line in file:
        do_things(line)
混沌鳄鱼 2017-11-15
  • 打赏
  • 举报
回复
硬盘IO接口是串行的,如果是机械硬盘因为就一个磁头在那里读写,文件分块读还可能增加寻道时间,最终也要排队,所以注定没有任何效果。 所以很明显比较快的方案: (1)如果内存足够,要把文件一次性连续到内存里的数据结构中 (2)读文件一定要用rb 二进制模式,用文本模式要处理换行符等控制符,效率要低很多 (3)CPU有几个核心进程池size就设几个 (4)把数据按进程池size分割处理,如省事就用list。 (5)结果合并
手无护鸡之力 2017-11-15
  • 打赏
  • 举报
回复
读模式改成 "rb"
extend 2017-11-15
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
[quote=引用 2 楼 extend 的回复:] [quote=引用 1 楼 oyljerry 的回复:]

with open('filename') as file:
    for line in file:
        do_things(line)
多谢版主,你给的写法实际就是我上面的第一种单线程写法,我运行了下,两者执行时间也基本一致。 但我的问题是,多进程并行为啥慢那么多呢?是我上面多进程并行代码写的不够优化,算法不对?还是在这种场景下,多并行本来就比不过单线程?还是数据量不够大,多进程体现不出优势?[/quote] 你可以把文件拆成多个,然后多个进程并行读,那么会有改进。不然你是一个读取文件,然后多个来统计,并不会改进还可能变慢[/quote] 看看我的理解对不: fb=fp.readlines(1048576),这样分开读文件(始终还是一个文件),再计算还不够并行;需要把"D:\Centos7\catalina.out"文件分拆成若干文件,再分别读取计算,这样才能高效并行,对吗? 也就是说并行处理的层次还不够? fp=open("D:\Centos7\catalina.out","r",encoding="UTF-8") ff=[] while 1: fb=fp.readlines(1048576) #65536(字节)*16*10,64kb*16=1024KB=1MB, if not fb: break ff.append(fb) fp.close()
oyljerry 2017-11-15
  • 打赏
  • 举报
回复
引用 2 楼 extend 的回复:
[quote=引用 1 楼 oyljerry 的回复:]

with open('filename') as file:
    for line in file:
        do_things(line)
多谢版主,你给的写法实际就是我上面的第一种单线程写法,我运行了下,两者执行时间也基本一致。 但我的问题是,多进程并行为啥慢那么多呢?是我上面多进程并行代码写的不够优化,算法不对?还是在这种场景下,多并行本来就比不过单线程?还是数据量不够大,多进程体现不出优势?[/quote] 你可以把文件拆成多个,然后多个进程并行读,那么会有改进。不然你是一个读取文件,然后多个来统计,并不会改进还可能变慢

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧