随着输出文件变大,Python file.write变慢

时间:2013-01-11 11:24:14

标签: python file-io python-2.7 windows-server-2008-r2

我对Python很新,但我有一个痛苦的问题。 我收到了一个程序,它读取一个infile(文本),更改一些值,并写一个outfile(也是文本)。 随着outfile变大,写入变得越来越慢,使得在2 MB之后变得无法忍受。 为什么会这样?我已经尝试改变代码以使用不同大小的缓冲区,并且我已经改变它以在写入之前将数据缓存到更大的块(字符串)中。我也试过连接而不是+ =来创建要写的字符串。没有这些对性能有任何不同 - 除了写更大的块,实际上使代码SLOWER。(!!!)

这是写outfile的方法。我将写入部分从单独的方法移动到内联:

for ifile in _file_stripper(f_in):
    parse_infile(ifile)
    date = variable_data['arkiveringsdatum']
    variable_data['arkiveringsdatum'] = datetime( int(date[0:4]), int(date[4:6]), int(date[6:8]), tzinfo=TZ()).isoformat('T')
    _personnr= variable_data['personnr'].replace('-', '').split(' ')[0]
    tmplist = ['<utskriftsstatus><brevid_kalla>', variable_data['brevid_kalla'], '</brevid_kalla><mapp>Se Allt</mapp><tidpunkt>', variable_data['arkiveringsdatum'], '</tidpunkt><dokumentpaket>', variable_data['dokumenttyp'], '</dokumentpaket><status>Utskriven</status><rensningsdatum>999999</rensningsdatum><kundid_gdb>', variable_data['kundid_gdb'], '</kundid_gdb><personnr>', _personnr, '</personnr></utskriftsstatus>']
    f_out.write(''.join(tmplist))

方法_file_stripper将大文件拆分为记录。 Infiles是5-21 MB。

请告知在哪里寻找错误。 当我谈到减速时,写入速度在写入大约1 MB后写入速度低于4KB /秒,随着outfile变大,它会不断下降。

编辑:根据要求,这里是parse_infile和_file_stripper:

def parse_infile(f_in):
   index = ""     #variabel som håller vilken ondemandvariabel vi läser in
   found_data = 0  #1 ifall vi hittat det vi letar efter annars 0
   for row in f_in:
      if( 'personnr' in row):
         found_data=1
         index = "personnr"
      elif( 'kundid_gdb' in row):
         found_data=1
         index = "kundid_gdb"
      elif( 'brevid_kalla' in row):
         found_data=1
         index = "brevid_kalla"
      elif( 'arkiveringsdatum' in row):
         found_data=1
         index = "arkiveringsdatum"
      elif( 'GROUP_FILENAME' in row ):
         variable_data['dokumenttyp'] = row.split(':')[-1].split('.')[2].capitalize()
      elif(found_data==1):
         variable_data[index] = row.split(':')[1].strip() 
         index = ""  #Nollställ index ifall värden saknas i filen
         found_data=0
      else:
         pass

def _file_stripper(tot_file):
   try:
      myfile = []
      for rows in tot_file:
         if not 'GROUP_FILENAME' in rows:
            myfile.append(rows)
         else:
            myfile.append(rows)
            yield myfile
   except Exception:
      pass

variable_data = { "brevid_kalla": "", "arkiveringsdatum": "", 
          "kundid_gdb": "", "personnr": "",
          "dokumenttyp": "" }

2 个答案:

答案 0 :(得分:1)

最有可能发生的事情是,variable_data,或者更有可能的是,其中的某些字段与每个已解析的文件一起成长。

你的parse_infile函数可能不会重置它并将新文件的值附加到已经存在的值,使得每个文件读取的值都会变大 - 这会导致在你描述的(O²)中使用资源。

最好的实践是不要依赖全局变量 - 让你的parse_infile函数在每次交互时创建一个新的字典,并将其返回给调用者。在主函数上,将函数的返回值赋给字典:

def parse_infile(file_):
    variable_data = {}
    (...)
    return variable_data

(...)
for ifile in _file_stripper(f_in):
    variable_data = parse_infile(ifile)
    (...)

答案 1 :(得分:0)

您的_file_stripper函数无休止地添加到myfile列表,而无需重置列表:

def _file_stripper(tot_file):
   try:
      myfile = []
      for rows in tot_file:
         if not 'GROUP_FILENAME' in rows:
            myfile.append(rows)
         else:
            myfile.append(rows)
            yield myfile
   except Exception:
      pass

请注意,myfile设置在循环外部,每行都附加到myfile,然后按原样生成。因此,您的进程内存占用量将增长和增长,从而迫使操作系统最终开始交换内存,从而减慢您的进程速度。

我认为您的意思是在myfile {{}}}中没有出现GROUP_FILENAME时重置rows

def _file_stripper(tot_file):
   try:
      myfile = []
      for rows in tot_file:
         if not 'GROUP_FILENAME' in rows:
            myfile.append(rows)
         else:
            myfile.append(rows)
            yield myfile
            myfile = []
   except Exception:
      pass
相关问题