Как сохранить считываемый элемент данных по элементам эффективным способом памяти? - PullRequest
0 голосов
/ 07 февраля 2019

Программа, над которой я работаю, нуждается в чтении в файлах данных, которые могут быть достаточно большими (до 5 ГБ) в ASCII.Формат может варьироваться, поэтому я решил использовать readline(), разбить каждую строку, чтобы получить только чистые записи, добавить их все в один большой список строк и разделить его на меньшие списки строк в зависимости от появления определенных слов-маркеров.и затем передают данные во внутреннюю структуру данных программы для дальнейшей унифицированной обработки.Этот метод работает достаточно хорошо, за исключением того, что ему требуется много памяти , и я удивляюсь, почему.

Итак, я написал небольшой тестовый пример, который поможет вам понять мою проблему: входные данные здесьтекст Шекспира Ромео и Джульетты (на самом деле я ожидаю смешанного буквенно-числового ввода) - обратите внимание, что я хочу, чтобы вы сами копировали данные, чтобы все было ясно.Сценарий создает файл .txt, который затем снова считывается с помощью.Объем памяти origina l в этом случае составляет 153 КБ .Чтение этого файла с помощью ...

  • f.read () также дает вам одну строку размером 153 КБ .
  • f.readlines() дает список с одиночными строками для каждой строки с общим размером 420 КБ .
  • Разделение строковых строк f.readlines () на каждое свободное место и сохранение всех этих одиночныхзаписи в новом списке приводят к 1619 КБ использования памяти.

Поскольку эти цифры не кажутся проблемой , в этом случаефактор> 10 в увеличении требований к оперативной памяти t определенно равен единице для входных данных в порядке ГБ.

Я понятия не имею, почему это так или как этого избежать.С моей точки зрения, список - это просто структура указателей, указывающих на все значения, хранящиеся в списке (это также причина, по которой sys.getsizeof () в списке дает «неправильный» результат).Для самих значений не должно быть различий в памяти, если у меня есть «LONG STRING» или «LONG» + «STRING», поскольку оба используют одни и те же символы, что должно приводить к одинаковому количеству бит / байт.

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

# step1: http://shakespeare.mit.edu/romeo_juliet/full.html
# step2: Ctrl+A and then Ctrl+C
# step3: Ctrl+V after benchmarkText

benchmarkText = """ >>INSERT ASCII DATA HERE<< """

#=== import modules =======================================
from pympler import asizeof
import sys

#=== open files and safe data to a structure ==============
#-- original memory size
print("\n\nAll memory sizes are in KB:\n")
print("Original string size:")
print(asizeof.asizeof(benchmarkText)/1e3)
print(sys.getsizeof(benchmarkText)/1e3)

#--- write bench mark file
with open('benchMarkText.txt', 'w') as f:
    f.write(benchmarkText)

#--- read the whole file (should always be equal to original size)
with open('benchMarkText.txt', 'r') as f:
    # read the whole file as one string
    wholeFileString = f.read()    
    # check size:
    print("\nSize using f.read():")
    print(asizeof.asizeof(wholeFileString)/1e3)

#--- read the file in a list
listOfWordOrNumberStrings = []
with open('benchMarkText.txt', 'r') as f:
    # safe every line of the file
    listOfLineStrings = f.readlines()
    print("\nSize using f.readlines():")
    print(asizeof.asizeof(listOfLineStrings)/1e3)

    # split every line into the words or punctation marks
    for stringLine in listOfLineStrings:
        line = stringLine[:-1] # get rid of the '\n'
       # line = re.sub('"', '', line) # The final implementation will need this, however for the test case it doesn't matter.
        elemsInLine = line.split()
        for elem in elemsInLine:
            listOfWordOrNumberStrings.append(elem)
    # check size
    print("\nSize after splitting:")
    print(asizeof.asizeof(listOfWordOrNumberStrings)/1e3)

(я знаю, что я использую readlines () вместо readline () здесь -Я изменил его в этом тестовом примере, потому что думаю, что это облегчает понимание.)

...