Проблема производительности при разборе большого файла построчно - PullRequest
0 голосов
/ 11 января 2019

У меня есть набор из нескольких миллионов небольших чисел, хранящихся в файле

Я написал скрипт Python, который построчно считывает числа из текстового файла с разделителями табуляции, вычисляет напоминания и добавляет результат в выходной файл. По какой-то причине он потребляет много оперативной памяти (20 Гб оперативной памяти в Ubuntu для анализа миллиона чисел). Он также зависает из-за частых записей.

Как правильно настроить скрипт.

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 Мб памяти в Python.exe) и Ubuntu (10 Гб используемая память). Что может вызвать это несоответствие? Тысяча раз больше - это много.

его скрипт потребляет около 20 Мбайт в Windows 10 (выглядит как

1 Ответ

0 голосов
/ 11 января 2019

попробуйте что-то вроде этого. Обратите внимание, что файлы открываются и закрываются только один раз каждый, и цикл повторяется один раз для каждой строки.

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...