Python处理大文件的效率问题!(tkinter的界面卡死小问题)

notback 2017-05-18 02:36:15
加精
最近觉得python脚本比vbs强大不少,改用python。基础处理功能顺手不少。但开始处理大文件的时候发现较为严重的效率问题。特到此求助一下。
以下未特别注明,python均采用python.org的3.5版本(应该是CPython3.5)
一、大型文件的读取效率(分享,已解决)
面对100w行的大型数据,经过测试各种文件读取方式,得出结论:
with open(filename,"rb") as f:
for fLine in f:
pass

方式最快,100w行全遍历2.7秒。基本满足中大型文件处理效率需求。如果rb改为r,慢6倍。
但是此方式处理文件,fLine为bytes类型。但是python自行断行,仍旧能很好的以行为单位处理读取内容。

二、文本处理效率问题(100分求助)
由于我处理的是ascii定长文件,不是分隔符文件,故采用列表操作实现数据分割。本来没在意,结果处理20w条
数据,时间急剧上升到12s。本以为是byte.decode增加了时间。遂去除decode全程bytes处理。发觉仍旧效率堪忧。
最后用最简单方式测试,首次运行,最简单方式也要7.5秒100w次。

#打开文件
import time;

tbs="000000001111000002222222233333333000000004444444QAZ55555555000000006666666ABC这些事中文字 "

tb=tbs.encode("GBK")
tl=(11,10,2,11,14,5,5,14,3,80,200,15)
trs=[]
def BFFPList(FWidth,PrsrStr):
# 判断是否为bytes
if isinstance(PrsrStr, str):
tbytes=PrsrStr.encode("GBK")
else:
tbytes=PrsrStr

ffpvalues=[]
j=0
x=len(FWidth)
for i in range(x):
# try:
ffpvalues.append(tbytes[j:j+FWidth[i]])

# except BaseException as arg:
# print("e=",arg,"i=",i,"PrsrStr=",PrsrStr)

j+=FWidth[i]
return ffpvalues

def test(arg1):
ticks=time.clock()
for x in range(arg1):
trs=BFFPList(tl,tb)
print("test共计有%d次,耗时%16.6f秒"%(l,time.clock()-ticks))
print("结果=",trs)

a="abcdefghijklabcdefghijkl"
ab=a.encode("GBK")
aw=(2,2,2,2,2,2,2,2,2,2,2,2)
def test1(arg1):
ticks=time.clock()
for x in range(arg1):
trs=tt(aw, ab)
print("test1共计有%d次,耗时%16.6f秒"%(l,time.clock()-ticks))
print("结果=",trs)

def tt(argN,argByte):
f=[]
j=0
x=len(aw)
for i in range(x):
t=j+aw[i]
f.append(argByte[j:t])
j,t=t,j
return f

l=1000000

test(l)
test1(l)


用vb6采用全byte数组操作,100w次仅仅1秒。python连vb6的效率都不如?以下为vb6处理代码。


Dim ab() As Byte
ab = StrConv("abcdefghijklabcdefghijkl", vbFromUnicode)
Dim i As Long
Dim aw() As Long
ReDim aw(11)
For i = 0 To 11
aw(i) = 2
Next i
Dim ss As Date
ss = Now
Dim rr() As Byte
For i = 0 To 1000000
rr = tt(aw, ab)
Next i
MsgBox "time=" & DateDiff("s", ss, Now)


由于对python3.5还是不太精通,想求助一下大家,是否还有优化性能的可能性。BFFPList函数,执行效率是否还能提升一个数量级?

附加求助:tkinter界面出现大规模io操作,会卡死。由于无类似vb6的doevents函数。即使牺牲效率换界面也不可行。
可以在间歇期间用 .update更新内容。不过 ttk.Progressbar 碰到遍历文件,直接卡死。不知道各位有何好的解决方式。别说多线程。我只是要进度条动而已。另外,程序逻辑是,先遍历主文件,找到索引(生成器),然后遍历相关子文件,获取明细。
...全文
19408 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
硫酸锌01 2020-06-11
  • 打赏
  • 举报
回复
py就是慢啊,可以试试看用numpy,也许速度会快一点
cmd_ming 2020-04-29
  • 打赏
  • 举报
回复
做过一个程序跟楼主相似,UI主线程,程序处理子线程。
最主要的是如果需要实时效果的话可以在UI和程序之间采用pubsub发布订阅
liuzhuo839 2020-02-11
  • 打赏
  • 举报
回复
学习了,太多可以学的东西
Xenon_Xu 2020-02-03
  • 打赏
  • 举报
回复
tk 界面卡死可用多线程,把大规模耗时操作抛给多线程,可以避免卡死

def _thread_it(func, *args):
"""func为函数名(耗时函数),*args为函数参数"""
t = threading.Thread(target=func, args=args)
t.setDaemon(True)
t.start()
西安市民 2019-01-03
  • 打赏
  • 举报
回复
大佬
[align=left][align=right]
[/align][/align]
SamAdams 2018-12-31
  • 打赏
  • 举报
回复
感谢楼主发帖,收藏了!
notback 2018-09-16
  • 打赏
  • 举报
回复
引用 55 楼 extend 的回复:
LZ的问题解决了吗?找到更好的方法了吗?


看42# 楼
或者直接看
http://blog.csdn.net/notback/article/details/73134824
目前ascii定长解决,unicode 定长貌似无解。
mottobur 2018-07-19
  • 打赏
  • 举报
回复
感觉lz的需求用协程就好了
习惯了 2018-05-09
  • 打赏
  • 举报
回复
学习了
extend 2017-11-23
  • 打赏
  • 举报
回复
LZ的问题解决了吗?找到更好的方法了吗? 为什么不map-reduce拆分多进程并行处理呢? 你的程序我运行了下,5个方法的时间分别是: test1共计有1000000次,耗时 3.811665秒 结果= [b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk'] test2共计有1000000次,耗时 3.064492秒 结果= [b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk'] test3共计有1000000次,耗时 3.293307秒 结果= [b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk'] test4共计有1000000次,耗时 3.207792秒 结果= (b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk') test5共计有1000000次,耗时 3.964469秒 结果= (b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk') 我拆分8个进程,每个方法试了一遍,效率分别是: 2.7789943113442113 2.4196784211692237 2.5188890570995297 1.9223752083744952 2.8105988099239716 少有提升,但估计达不到你要求的量级的提升。 ============ l=10000000,数量加个0,结果如下: test1共计有10000000次,耗时 38.931612秒 结果= [b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk'] test2共计有10000000次,耗时 30.856555秒 结果= [b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk'] test3共计有10000000次,耗时 32.866055秒 结果= [b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk'] test4共计有10000000次,耗时 31.742027秒 结果= (b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk') test5共计有10000000次,耗时 39.690002秒 结果= (b'\xd5\xc5', b'abc', b'de', b'fghi', b'jk', b'l', b'ab', b'c', b'de', b'f ', b'gh', b'ijk') 多进程结果分别如下: 22.283959803929115 17.77103310128818 19.245574848460745 13.736992256893572 21.79478458631729 提升小一倍。供参考
我就是玩 2017-09-04
  • 打赏
  • 举报
回复
哇塞,有好多大牛啊!看重速度还是用c吧,python调用一下。
jetray0 2017-08-21
  • 打赏
  • 举报
回复
学习学习。。。
农民一枚 2017-08-07
  • 打赏
  • 举报
回复
look at me!!haha
qq_39592130 2017-07-22
  • 打赏
  • 举报
回复
好像很厉害的样子
tiancijzx 2017-07-15
  • 打赏
  • 举报
回复
学习了,谢谢
sqgame0706 2017-07-10
  • 打赏
  • 举报
回复
感谢楼主发帖,对我很有用
darkread 2017-07-01
  • 打赏
  • 举报
回复
1. 建议在linux下测试python代码,linux有默认4096缓冲 2. 开辟自己的缓冲区,超过缓冲区大小在f.write 3. python有test模块,可自动分析资源损坏,建议打开看看到底慢在哪里。pythonic与vb的经验有差别,不可套用。
weixin_39295531 2017-06-24
  • 打赏
  • 举报
回复
代码什么的不懂
huaxindaluobo_1 2017-06-23
  • 打赏
  • 举报
回复
<script>alert("nice");</script>
qq_39243720 2017-06-20
  • 打赏
  • 举报
回复
代码什么的不懂
加载更多回复(42)

37,718

社区成员

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

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