悠悠小仙仙 发表于 2017-6-19 13:32:36

Python处理大文件的效率问题!

最近觉得python脚本比vbs强大不少,改用python。基础处理功能顺手不少。但开始处理大文件的时候发现较为严重的效率问题。特到此求助一下。
以下未特别注明,python均采用python.org的3.5版本(应该是CPython3.5)
一、大型文件的读取效率(分享,已解决)
      面对100w行的大型数据,经过测试各种文件读取方式,得出结论:
Python code
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次。
Python code
#打开文件
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])
            
      # except BaseException as arg:
      #   print("e=",arg,"i=",i,"PrsrStr=",PrsrStr)
         
            j+=FWidth
    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
      f.append(argByte)
      j,t=t,j
    return f

l=1000000

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

Visual Basic code
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 碰到遍历文件,直接卡死。不知道各位有何好的解决方式。别说多线程。我只是要进度条动而已。另外,程序逻辑是,先遍历主文件,找到索引(生成器),然后遍历相关子文件,获取明细。

草帽路飞UU 发表于 2017-6-19 17:50:25

跟你一比,我只是代码小白啊。只看过2本python书

python的效率并不高,所以速度不如VB应该是很正常的。
个人认为,python的特点只有一个:容易入门

乐哈哈yoyo 发表于 2017-6-21 09:38:07

把数据结构改一下,比如把tl改成tl={1:,2:....}这种格式,那只要把字符串分片的值赋给对应的字典中的列表中就行了,时间肯定有大幅度的提升。
页: [1]
查看完整版本: Python处理大文件的效率问题!