web-dev-qa-db-fra.com

Taille de la mémoire de la variable dans Python

J'écris Python code pour faire un calcul de grand nombre, et avoir de sérieuses préoccupations sur la mémoire utilisée dans le calcul.

Ainsi, je veux compter chaque bit de chaque variable.

Par exemple, j'ai une variable x, qui est un grand nombre, et je veux compter le nombre de bits pour représenter x.

Le code suivant est évidemment inutile:

x=2**1000
len(x)

Ainsi, je me tourne pour utiliser le code suivant:

x=2**1000
len(repr(x))

La variable x est (en décimal) est:

10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

mais le code ci-dessus renvoie

La longue séquence ci-dessus a une longueur de 302, et donc je crois que devrait être liée à la longueur de la chaîne uniquement.

Alors, voici ma question initiale:

Comment puis-je connaître la taille de la mémoire de la variable x?

Une dernière chose en langage C/C++, si je définis

int z=1;

Cela signifie qu'il y a 4 octets = 32 bits alloués pour z et que les bits sont disposés en 00..001 (31 0 et un 1).

Ici, ma variable x est énorme, je ne sais pas si elle suit la même règle d’allocation de mémoire?

46
user4478

Utilisation sys.getsizeof pour obtenir la taille d'un objet, en octets.

>>> from sys import getsizeof
>>> a = 42
>>> getsizeof(a)
12
>>> a = 2**1000
>>> getsizeof(a)
146
>>>

Notez que la taille et la disposition d'un objet sont purement spécifiques à l'implémentation. CPython, par exemple, peut utiliser des structures de données internes totalement différentes de celles d'IronPython. La taille d'un objet peut donc varier d'une implémentation à l'autre.

91
Jonathon Reinhart

En ce qui concerne la structure interne d'un Python long, vérifiez sys.int_info (ou sys.long_info pour Python 2.7).

>>> import sys
>>> sys.int_info
sys.int_info(bits_per_digit=30, sizeof_digit=4)

Python stocke soit 30 bits dans 4 octets (la plupart des systèmes 64 bits), soit 15 bits dans 2 octets (la plupart des systèmes 32 bits). En comparant l'utilisation réelle de la mémoire avec les valeurs calculées, je reçois

>>> 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

Il y a 24 octets de surcharge pour 0 car aucun bit n'est stocké. La mémoire requise pour des valeurs plus grandes correspond aux valeurs calculées.

Si vos nombres sont si importants que vous vous inquiétez des 6,25% de bits non utilisés, vous devriez probablement consulter la bibliothèque gmpy2 . La représentation interne utilise tous les bits disponibles et les calculs sont nettement plus rapides pour les grandes valeurs (par exemple, supérieures à 100 chiffres).

5
casevh