代码之家  ›  专栏  ›  技术社区  ›  Stepan

逐行分析大文件时的性能问题

  •  0
  • Stepan  · 技术社区  · 6 年前

    我在一个文件中存储了数百万个小数字

    我编写了一个python脚本,它逐行读取以制表符分隔的文本文件中的数字,计算提醒并将结果附加到输出文件中。出于某种原因,它消耗了大量的ram(ubuntu上20gb的ram可以解析一百万个数字)。由于频繁的写入,它也会冻结系统。

    调整这个脚本的正确方法是什么?

    import os
    import re
    
    my_path = '/media/me/mSata/res/'
    # output_file.open() before the first loop didn't help
    
    for file_id in range (10,11): #10,201
        filename = my_path + "in" + str(file_id) + ".txt"
    
        fstr0 = ""+my_path +"out"+ str(file_id)+"_0.log"
        fstr1 = ""+my_path +"res"+ str(file_id)+"_1.log"
    
        with open(filename) as fp:
            stats = [0] * (512)
    
            line = fp.readline()
    
            while line:
                raw_line = line.strip()
                arr_of_parsed_numbers = re.split(r'\t+', raw_line.rstrip('\t'))
    
                for num_index in range(0, len(arr_of_parsed_numbers)):
                    my_number = int(arr_of_parsed_numbers[num_index])
    
                    v0 = (my_number % 257) -1     #value 257 is correct
                    my_number = (my_number )//257   
                    stats[v0] += 1
                    v1 = my_number % 256
                    stats[256+v1]+=1
    
                    f0 = open(fstr0, "a")
                    f1 = open(fstr1, "a")
    
                    f0.write("{}\n".format(str(v0).rjust(3)))
                    f1.write("{}\n".format(str(v1).rjust(3)))
                    f0.close()
                    f1.close() 
    
                line=fp.readLine()
    
        print(stats)
    
    # tried output_file.close() here as well
    print("done")
    

    更新: 我在windows 10(10)下运行了这个脚本 MB python.exe中的内存)和ubuntu(10 GB 内存消耗)。什么会导致这种差异?一千倍多就是很多。

    他的脚本在Windows10上消耗了大约20MB(看起来

    1 回复  |  直到 6 年前
        1
  •  0
  •   stackPusher    6 年前

    试试这样的。注意,每个文件只打开和关闭一次,循环每行迭代一次。

    import os
    import re
    
    my_path = '/media/me/mSata/res/'
    # output_file.open() before the first loop didn't help
    
    for file_id in range (10,11): #10,201
        filename = my_path + "in" + str(file_id) + ".txt"
    
        fstr0 = ""+my_path +"out"+ str(file_id)+"_0.log"
        fstr1 = ""+my_path +"res"+ str(file_id)+"_1.log"
    
        with open(filename, "r") as fp, open(fstr0, "a") as f0, open(fstr1, "a") as f1:
            stats = [0] * (512)
    
            for line in fp:
                raw_line = line.strip()
                arr_of_parsed_numbers = re.split(r'\t+', raw_line.rstrip('\t'))
    
                for num_index in range(0, len(arr_of_parsed_numbers)):
                    my_number = int(arr_of_parsed_numbers[num_index])
    
                    v0 = (my_number % 257) -1     #value 257 is correct
                    my_number = (my_number )//257   
                    stats[v0] += 1
                    v1 = my_number % 256
                    stats[256+v1]+=1
    
                    f0.write("{}\n".format(str(v0).rjust(3)))
                    f1.write("{}\n".format(str(v1).rjust(3)))
    
        print(stats)
    
    # tried output_file.close() here as well
    print("done")