Размер переменной памяти в Python
Я пишу код Python для вычисления большого числа чисел и серьезно беспокоюсь о памяти, используемой при вычислении.
Таким образом, я хочу считать каждый бит каждой переменной.
Например, у меня есть переменная x, которая является большим числом и хочет подсчитать количество бит для представления x.
Следующий код, очевидно, бесполезен:
x=2**1000
len(x)
Таким образом, я перехожу к использованию следующего кода:
x=2**1000
len(repr(x))
Переменная x равна (в десятичной форме):
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
но приведенный выше код возвращает 303
Вышеупомянутая длинная длинная последовательность имеет длину 302, поэтому я считаю, что 303 должен быть связан только с длиной строки.
Итак, вот мой оригинальный вопрос:
Как узнать размер памяти переменной x?
Еще одна вещь; в языке C/С++, если я определяю
int z=1;
Это означает, что для z выделено 4 байта = 32 бита, а биты расположены как 00..001 (31 0 и один 1).
Здесь моя переменная x огромна, я не знаю, следует ли ей одно и то же правило распределения памяти?
Ответы
Ответ 1
Используйте sys.getsizeof
, чтобы получить размер объекта в байтах.
>>> from sys import getsizeof
>>> a = 42
>>> getsizeof(a)
12
>>> a = 2**1000
>>> getsizeof(a)
146
>>>
Обратите внимание, что размер и макет объекта являются специфическими для реализации. Например, CPython может использовать совершенно разные внутренние структуры данных, чем IronPython. Таким образом, размер объекта может варьироваться от реализации к реализации.
Ответ 2
Что касается внутренней структуры Python long, проверьте sys.int_info (или sys.long_info для Python 2.7).
>>> import sys
>>> sys.int_info
sys.int_info(bits_per_digit=30, sizeof_digit=4)
Python либо хранит 30 бит в 4 байта (большинство 64-разрядных систем), либо 15 бит в 2 байта (большинство 32-разрядных систем). Сравнивая фактическое использование памяти с вычисленными значениями, я получаю
>>> import math, sys
>>> a=0
>>> sys.getsizeof(a)
24
>>> a=2**100
>>> sys.getsizeof(a)
40
>>> a=2**1000
>>> sys.getsizeof(a)
160
>>> 24+4*math.ceil(100/30)
40
>>> 24+4*math.ceil(1000/30)
160
Есть 24 байта служебных данных для 0, поскольку никакие биты не сохраняются. Требования к памяти для больших значений соответствуют рассчитанным значениям.
Если ваши номера настолько велики, что вас беспокоят 6,25% неиспользуемых битов, вам, вероятно, стоит посмотреть библиотеку gmpy2. Внутреннее представление использует все доступные биты, и вычисления значительно быстрее для больших значений (например, более 100 цифр).