Question

Par exemple, combien de mémoire faut-il pour stocker une liste d'un million d'entiers (32 bits)?

alist = range(1000000) # or list(range(1000000)) in Python 3.0
Était-ce utile?

La solution 2

Liens utiles:

Comment obtenir la taille de la mémoire / l'utilisation de l'objet python

Taille de la mémoire des objets en python?

si vous mettez des données dans un dictionnaire, comment calculons-nous la taille des données ?

Cependant, ils ne donnent pas de réponse définitive. Le chemin à parcourir:

  1. Mesurez la mémoire utilisée par l'interpréteur Python avec / sans la liste (utilisez les outils du système d'exploitation).

  2. Utilisez un module d'extension tiers qui définit une sorte de sizeof (PyObject).

Mettre à jour :

Recette 546530: Taille des objets Python (révisée)

import asizeof

N = 1000000
print asizeof.asizeof(range(N)) / N
# -> 20 (python 2.5, WinXP, 32-bit Linux)
# -> 33 (64-bit Linux)

Autres conseils

"Cela dépend." Python alloue de la place pour les listes de manière à atteindre le temps constant amorti pour l'ajout d'éléments à la liste.

En pratique, cela signifie avec l'implémentation actuelle: la liste a toujours un espace alloué pour un nombre de puissance égal à deux. Ainsi, range (1000000) allouera une liste assez grande pour contenir 2 ^ 20 éléments (~ 1,045 million).

Il s’agit uniquement de l’espace requis pour stocker la structure de liste elle-même (qui est un tableau de pointeurs sur les objets Python pour chaque élément). Un système 32 bits nécessitera 4 octets par élément, un système 64 bits utilisera 8 octets par élément.

De plus, vous avez besoin d’espace pour stocker les éléments réels. Cela varie beaucoup. Pour les petits entiers (actuellement de -5 à 256), aucun espace supplémentaire n'est nécessaire, mais pour les grands nombres, Python alloue un nouvel objet pour chaque entier, ce qui prend 10 à 100 octets et tend à fragmenter la mémoire.

En bout de ligne: c'est compliqué et les listes Python ne sont pas un bon moyen de stocker de grandes structures de données homogènes. Pour cela, utilisez le module array ou, si vous devez faire des calculs vectoriels, utilisez NumPy.

PS - Les tuples, contrairement aux listes, ne sont pas conçus pour y être ajoutés progressivement. Je ne sais pas comment fonctionne l'allocateur, mais je ne pense même pas à l'utiliser pour les grandes structures de données: -)

Adressage " tuple " une partie de la question

La déclaration de PyTuple de CPython dans une configuration de construction typique se résume à ceci:

struct PyTuple {
  size_t refcount; // tuple's reference count
  typeobject *type; // tuple type object
  size_t n_items; // number of items in tuple
  PyObject *items[1]; // contains space for n_items elements
};

La taille de l'instance PyTuple est fixée lors de sa construction et ne peut plus être modifiée par la suite. Le nombre d’octets occupés par PyTuple peut être calculé comme suit:

  

sizeof (size_t) x 2 + sizeof (void *) x (n_items + 1) .

Ceci donne une taille peu profonde du tuple. Pour obtenir la taille complète , vous devez également ajouter le nombre total d'octets consommés par le graphe d'objet enraciné dans le tableau PyTuple :: items [] .

Il est à noter que les routines de construction de tuple garantissent la création d'une seule instance de tuple vide (singleton).

Références: Python.h , object.h , tupleobject.h , tupleobject.c

  

Une nouvelle fonction, getsizeof () , prend une   Objet Python et renvoie le montant   de la mémoire utilisée par l'objet, mesurée   en octets. Retour d'objets intégrés   corriger les résultats; tierce personne   les extensions ne peuvent pas, mais peuvent définir un    __ méthode sizeof __ () pour renvoyer la taille de l'objet & # 8217; s.

kveretennicov@nosignal:~/py/r26rc2$ ./python
Python 2.6rc2 (r26rc2:66712, Sep  2 2008, 13:11:55) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
>>> import sys
>>> sys.getsizeof(range(1000000))
4000032
>>> sys.getsizeof(tuple(range(1000000)))
4000024

Les numéros renvoyés n'incluent évidemment pas la mémoire consommée par les objets contenus (sys.getsizeof (1) == 12).

Ceci est spécifique à la mise en œuvre, j'en suis sûr. Cela dépend certainement de la représentation interne des entiers - vous ne pouvez pas présumer qu'ils seront stockés au format 32 bits, car Python vous donne des entiers arbitrairement grands, de sorte que de petites entières sont peut-être stockées de manière plus compacte.

Sur mon Python (2.5.1 sur Fedora 9 sur le duo 2), VmSize avant allocation est de 6896 Ko, après de 22684 Ko. Après un million d'affectations supplémentaires, VmSize passe à 38340 ko. Cela indique très grossièrement environ 16 000 Ko pour les 1 000 000 entiers, ce qui correspond à environ 16 octets par entier. Cela suggère un lot de frais généraux pour la liste. Je prendrais ces chiffres avec une grosse pincée de sel.

Je me méfie de la raison pour laquelle vous demandez. Essayez-vous de savoir combien de mémoire vous aurez besoin pour une implémentation donnée? Dis, tu vas lire 10 000 000 de widgets et tu veux savoir combien de RAM ça va aspirer?

Si tel est le cas, plutôt que d'essayer de déterminer la quantité de RAM utilisée par chaque widget, déterminez la quantité de RAM, disons, 10 000 widgets, puis multipliez-la pour obtenir votre taille réelle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top