HOWTO · Python

Déterminer la taille d'un objet en Python

Ce tutoriel explique comment déterminer la taille d'un objet en Python.

Sur cette page

Utilisez sys.getsizeof() pour obtenir la taille superficielle d’un objet, en octets. Cette fonction ne comptabilise pas la taille des objets auxquels celui-ci fait référence. Pour estimer récursivement la taille d’un conteneur et de son contenu, utilisez Pympler ; pour comparer les allocations Python au fil du temps, utilisez tracemalloc.

Mesurer la taille superficielle d’un objet avec sys.getsizeof()

Importez sys et passez à sys.getsizeof() la valeur que vous souhaitez examiner. L’entier renvoyé indique la taille superficielle de l’objet en octets. Par exemple, il correspond à l’objet liste lui-même, mais ne comprend pas les objets qu’il contient. Cette distinction est importante lorsqu’un conteneur référence de longues chaînes, des conteneurs imbriqués ou d’autres données.

Exécutez cet exemple pour mesurer un conteneur intégré à Python. Le nombre affiché est une valeur illustrative observée dans un environnement donné ; il dépend de l’implémentation et de la version de Python et ne constitue pas une valeur fixe valable partout. Le libellé de la sortie reste en anglais :

import sys

values = [10, 20, 30]
size_bytes = sys.getsizeof(values)
print(f"Shallow size: {size_bytes} bytes")
Shallow size: 88 bytes

Vous pouvez procéder de la même façon avec d’autres valeurs, comme une chaîne, un entier ou un dictionnaire. La taille indiquée peut elle aussi varier selon l’implémentation et la version de Python. Considérez ce résultat comme une mesure propre à l’implémentation, et non comme une garantie sur la mémoire totale du processus ou sur le coût de tous les objets accessibles depuis cette valeur.

Inclure les objets référencés avec Pympler

Pour obtenir une estimation qui inclut les objets accessibles depuis un conteneur, l’utilitaire asizeof de Pympler peut comptabiliser récursivement les objets référencés. Installez ce paquet tiers avec pip install pympler, puis importez asizeof depuis pympler et appelez-le sur la valeur à examiner.

Après avoir installé Pympler, exécutez cet exemple autonome :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

try:
    from pympler import asizeof
except ImportError:
    print("Install Pympler with: pip install pympler")
else:
    values = [1, 2, [3, 4]]
    print(f"Recursive size: {asizeof.asizeof(values)} bytes")

Le nombre indiqué dépend de l’implémentation et de la version de Python, ainsi que de la version de Pympler installée. Il s’agit donc d’une estimation pour ce graphe d’objets, et non d’une valeur fixe valable partout. Le libellé de la sortie reste en anglais.

Cette estimation récursive répond à une question différente de celle de sys.getsizeof() : elle inclut les objets imbriqués, et pas seulement la taille superficielle de l’objet externe. Elle reste une estimation du graphe d’objets, pas une mesure de l’ensemble du processus Python, de la surcharge de l’allocateur ni de la mémoire résidente indiquée par le système d’exploitation. Les références partagées et les détails de l’implémentation peuvent influer sur la façon dont un outil récursif comptabilise les objets. Utilisez donc cette mesure pour comparer des structures de façon cohérente, et non comme un total exact de la mémoire du processus.

Suivre les allocations mémoire avec tracemalloc

Utilisez le module de la bibliothèque standard tracemalloc pour observer les allocations mémoire Python effectuées pendant une partie d’un programme. Démarrez le suivi avant le travail qui vous intéresse, lisez les tailles actuellement suivie et maximale en octets, puis arrêtez le suivi une fois la mesure terminée. L’exemple autonome suivant alloue une liste pendant le suivi et affiche ces deux valeurs ; les nombres présentés sont des exemples observés dans un environnement donné et varient selon l’implémentation de Python et l’environnement d’exécution. Les libellés de la sortie restent en anglais :

import tracemalloc

tracemalloc.start()
values = [number for number in range(1000)]
current_bytes, peak_bytes = tracemalloc.get_traced_memory()
print(f"Current traced memory: {current_bytes} bytes")
print(f"Peak traced memory: {peak_bytes} bytes")
tracemalloc.stop()
Current traced memory: 29536 bytes
Peak traced memory: 29536 bytes

current_bytes correspond à la quantité actuellement suivie, tandis que peak_bytes indique le maximum suivi depuis le début du suivi. Celui-ci doit être actif avant une allocation pour l’enregistrer ; les valeurs concernent les allocations Python suivies, et non la taille retenue de façon récursive par un objet choisi. Pour rechercher l’origine des allocations, utilisez des instantanés ou comparez les valeurs à des moments pertinents. Arrêtez le suivi lorsque la mesure est terminée afin qu’il ne continue pas à collecter des données inutilement.