Подтвердить что ты не робот

Размер переменной памяти в 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 огромна, я не знаю, следует ли ей одно и то же правило распределения памяти?

4b9b3361

Ответ 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 цифр).