Измерение использования памяти с разными методами хранения
На этом этапе мы рассмотрим, как различные способы хранения данных могут повлиять на использование памяти. Использование памяти является важной частью программирования, особенно при работе с большими наборами данных. Чтобы измерить память, используемую нашим кодом на Python, мы будем использовать модуль tracemalloc
Python. Этот модуль очень полезен, так как позволяет отслеживать выделение памяти, выполняемое Python. С его помощью мы можем увидеть, сколько памяти потребляют наши методы хранения данных.
Метод 1: Хранение всего файла как одной строки
Начнем с создания нового файла на Python. Перейдите в каталог /home/labex/project
и создайте файл с именем memory_test1.py
. Вы можете использовать текстовый редактор для открытия этого файла. После открытия файла добавьте в него следующий код. Этот код прочитает весь контент файла как одну строку и измерит использование памяти.
## memory_test1.py
import tracemalloc
def test_single_string():
## Start tracking memory
tracemalloc.start()
## Read the entire file as a single string
with open('/home/labex/project/ctabus.csv') as f:
data = f.read()
## Get memory usage statistics
current, peak = tracemalloc.get_traced_memory()
print(f"File length: {len(data)} characters")
print(f"Current memory usage: {current/1024/1024:.2f} MB")
print(f"Peak memory usage: {peak/1024/1024:.2f} MB")
## Stop tracking memory
tracemalloc.stop()
if __name__ == "__main__":
test_single_string()
После добавления кода сохраните файл. Теперь, чтобы запустить этот скрипт, откройте терминал и выполните следующую команду:
python3 /home/labex/project/memory_test1.py
При запуске скрипта вы должны увидеть вывод, похожий на следующий:
File length: 12361039 characters
Current memory usage: 11.80 MB
Peak memory usage: 23.58 MB
Точные числа могут отличаться на вашей системе, но обычно вы заметите, что текущее использование памяти составляет около 12 МБ, а пиковое использование памяти - около 24 МБ.
Метод 2: Хранение в виде списка строк
Далее мы протестируем другой способ хранения данных. Создайте новый файл с именем memory_test2.py
в том же каталоге /home/labex/project
. Откройте этот файл в редакторе и добавьте следующий код. Этот код читает файл и хранит каждую строку как отдельную строку в списке, а затем измеряет использование памяти.
## memory_test2.py
import tracemalloc
def test_list_of_strings():
## Start tracking memory
tracemalloc.start()
## Read the file as a list of strings (one string per line)
with open('/home/labex/project/ctabus.csv') as f:
lines = f.readlines()
## Get memory usage statistics
current, peak = tracemalloc.get_traced_memory()
print(f"Number of lines: {len(lines)}")
print(f"Current memory usage: {current/1024/1024:.2f} MB")
print(f"Peak memory usage: {peak/1024/1024:.2f} MB")
## Stop tracking memory
tracemalloc.stop()
if __name__ == "__main__":
test_list_of_strings()
Сохраните файл и запустите скрипт, используя следующую команду в терминале:
python3 /home/labex/project/memory_test2.py
Вы должны увидеть вывод, похожий на следующий:
Number of lines: 577564
Current memory usage: 43.70 MB
Peak memory usage: 43.74 MB
Обратите внимание, что использование памяти значительно увеличилось по сравнению с предыдущим методом хранения данных как одной строки. Это происходит потому, что каждая строка в списке является отдельным объектом строки Python, и каждый объект имеет свою собственную накладную нагрузку по памяти.
Понимание разницы в использовании памяти
Разница в использовании памяти между двумя подходами демонстрирует важный концепт в программировании на Python, называемый накладной нагрузкой объекта. Когда вы храните данные в виде списка строк, каждая строка является отдельным объектом Python. Каждый объект имеет некоторые дополнительные требования к памяти, которые включают:
- Заголовок объекта Python (обычно 16 - 24 байта на объект). Этот заголовок содержит информацию о объекте, такую как его тип и счетчик ссылок.
- Фактическое строковое представление, которое хранит символы строки.
- Заполнение для выравнивания памяти. Это дополнительное пространство, добавленное для обеспечения правильного выравнивания адреса памяти объекта для эффективного доступа.
С другой стороны, когда вы храните весь контент файла как одну строку, есть только один объект, и, следовательно, только один набор накладных расходов. Это делает его более экономичным по памяти, если учитывать общий размер данных.
При проектировании программ, работающих с большими наборами данных, вы должны учитывать этот компромисс между эффективностью использования памяти и доступностью данных. Иногда может быть более удобно получать доступ к данным, когда они хранятся в списке строк, но это потребует больше памяти. В других случаях вы можете отдать предпочтение эффективности использования памяти и выбрать хранить данные как одну строку.