Опубликован: 26.10.2023 115
В Python данные хранятся в памяти в виде объектов.
Каждый объект представляет собой комбинацию самих значений данных и метаданных, таких как тип объекта и ссылки на другие объекты.
Каждая переменная является ссылкой на объект в памяти, что позволяет работать с данными эффективно и гибко.
Все объекты в Python с точки зрения использования памяти можно разделить на:
str
, int
, float
, bytes
, array.array
);list
, tuple
, set
, dict
).В памяти, занятой плоскими объектами, хранятся сами значения этих объектов, тогда как в контейнерных объектах хранятся только ссылки на объекты любого типа (плоские или контейнерные). Так например, списки - это массивы ссылок на Python-объекты, что позволяет хранить в них объекты различных типов.
Поэтому плоские объекты компактнее (занимают меньше памяти), но могут содержать только значения примитивных машинных типов, например байты, целые числа и числа с плавающей точкой.
В Python проверить использование памяти объектом можно с помощью функции sys.getsizeof()
модуля sys
, которая возвращает размер объекта в байтах:
import sys
# целое число (int) занимает 28 байт
sys.getsizeof(3)
28
sys.getsizeof(123456789) # целое 9-значное число занимает тоже 28 байт
28
sys.getsizeof(1234567891) # целое 10-значное число занимает уже на 4 байта больше
32
# число с плавающей точкой float занимает 24 байта
sys.getsizeof(7.2)
24
sys.getsizeof(123456789.123456789) # float с 9-значным числом занимает тоже 24 байта
24
# пустая строка str занимает 49 байт
sys.getsizeof('')
49
# строка из одного символа '1' всего 50 байт
sys.getsizeof('1')
50
# строка из 5-ти символов занимает 54 байта (+ по одному байту на символ)
sys.getsizeof('12345')
54
sys.getsizeof("Эта очень длинная строка занимает всего 188 байт памяти !")
188
Таким образом, мы видим, что простое и 9-ти значное целое число int
занимают одинаковый размер памяти (28 байт), а начиная с 10-ти значного целого числа добавляется еще 4 байта (до 32 байт).
Число с плавающей точкой float
занимает всего 24 байта независимо от значения числа и количества десятичных знаков.
Пустая строка занимает 49 байтов, а каждый символ строки добавляет еще один байт.
Все дело в том, что у объектов Python огромные фиксированные накладные расходы памяти.
#
my_list = [x for x in range(0, 10000)]
my_tuple = (x for x in range(0, 10000))
my_set = set(my_list)
print(sys.getsizeof(my_list))
85176
print(sys.getsizeof(my_tuple))
200
print(sys.getsizeof(my_set))
524504
Приведенный пример показывает, что большой список list
из 10000 элементов занимает 85176 байт памяти.
В отличие от списка кортеж tuple
из такого же количества элементов занимает всего 200 байт (или в 425 раз меньше).
А множество set
, созданное из того же списка, требует в 6.15 раз больше памяти. Это результат использования множеством хеш-таблицы, которая хранится в памяти и позволяет производить над множествами вычисления гораздо быстрее, чем аналогичные операции со списками.
В Python наиболее экономное использование памяти обеспечивают объекты-генераторы (такие, как например функция range()
):
import sys
my_list = range(0, 10000)
print(sys.getsizeof(my_list))
48
Оценка основных статистических метрик набора данных в Python
Область эффективного использования lambda функции в Python
Логические выражения if ... else в Pythonic стиле
Способы удаления лишних пробелов в строке
Комментариев нет.