Utilisez ces conseils pour analyser votre code et découvrir où il est le plus ou le moins efficace.

Comme "il y a plus d'une façon de le faire" en Python, trouver l'approche la plus efficace en mémoire pour certaines tâches peut être difficile. C'est là qu'un profileur de mémoire peut vous aider. En plus de suivre les fuites, l'estimation du profil de mémoire de votre code permet de déterminer quel code est économe en mémoire.

Que vous développiez un modèle d'apprentissage automatique ou un site Web avec Python, vous pouvez estimer le profil de mémoire pour les scripts, les lignes de code individuelles ou les fonctions.

L'estimation du profil de mémoire de l'ensemble de votre base de code peut s'avérer peu pratique, car cela peut ralentir considérablement votre application. Il est préférable de profiler de manière sélective les fonctions ou les méthodes que vous soupçonnez de consommer davantage de mémoire. Mais même si vous souhaitez le faire pour l'ensemble de votre application, vous souhaiterez peut-être dédier un module isolé pour le gérer.

instagram viewer

Il existe de nombreuses bibliothèques de profilage en Python. Certains des plus populaires sont profil_mémoire, psutil, Tracemalloc, et pympler. Ce tutoriel utilise profil_mémoire et psutil.

Alors que psutil est idéal pour estimer la consommation mémoire totale de l'exécution d'une méthode ou d'une fonction, profil_mémoire fournit des informations plus détaillées sur l'utilisation de la mémoire, y compris les tendances d'utilisation ligne par ligne et au niveau fonctionnel au fil du temps.

Pour commencer, installez profil_mémoire dans votre environnement virtuel Python. Cela installe également psutil.

pip installer memory_profiler

Obtenir la taille d'un objet en mémoire

Vous pouvez commencer votre profilage de la mémoire en calculant d'abord la taille d'un objet que vous avez l'intention d'utiliser en mémoire.

Ce type de profilage est utile au début du développement, tout en essayant de déterminer quel type d'objet utiliser dans un programme.

Par exemple, si vous ne parvenez pas à décider quelles méthodes utiliser pour accomplir une tâche, disons, la méthode appropriée Type de données Python, vous pouvez obtenir la taille de chacun en octets pour déterminer lequel est le plus léger pour votre utilisation cas.

Le sys.getsizeof la méthode intégrée est utile ici :

importer système
imprimer(f"taille de la liste: {sys.getsizeof([])} octets")
imprimer(f"taille du dictionnaire: {sys.getsizeof (dict)} octets")
imprimer(f"taille du tuple: {sys.getsizeof())} octets")
imprimer(f"taille définie: {sys.getsizeof({})} octets")

Voici la sortie :

Vous pouvez également utiliser le sys.getsizeof méthode pour comparer la taille de la mémoire d'une fonction intégrée et personnalisée.

Par exemple, comparez cette fonction de longueur personnalisée qui utilise une boucle for Python avec le module intégré len fonction:

importer système

définitivementobtenirLongueur(itérable):
compter = 0

pour je dans itérable :
compter +=1

retour compter

imprimer(f"Fonction de longueur intégrée: {sys.getsizeof (len)} octets")
imprimer(f"Fonction de longueur personnalisée: {sys.getsizeof (getLength)} octets")

Le code ci-dessus donne la sortie suivante :

Cependant, alors que sys.getsizeof mesure la taille d'un objet en mémoire, il ne tient compte que de l'objet lui-même et non de ceux qui le référencent. Pour cela, vous aurez besoin d'une méthode de profilage plus détaillée.

Trouver le profil de mémoire d'une fonction Python

Vous pouvez obtenir un profil mémoire plus détaillé de chaque ligne de code d'une fonction en utilisant le profil_mémoire emballer. Cela consiste à ajouter le @profil décorateur à votre fonction ou méthode :

importer des pandas
importer numpy
à partir du profil d'importation memory_profiler

classe Manipuler :
@profil
def manipuleData (soi):
df = pandas. Trame de données({
'A' :[0, 3, numpy.nan, 10, 3, numpy.nan],
'B': [numpy.nan, "Pandas", numpy.nan, "Pandas", "Python", "JavaScript"],
})

df.fillna (method='bfill', inplace=True)
df.fillna (method='ffill', inplace=True)
chaîne de retour (df)

manip = Manipuler()
imprimer (manip.manipulateData())

Le code ci-dessus donne un profil de mémoire détaillé de chaque ligne de code dans la fonction comme indiqué :

Le Utilisation de la mémoire indique l'utilisation de la mémoire pour une ligne de code particulière, tandis que la Incrément La colonne indique la surcharge apportée par chaque ligne. Le Occurrence La colonne définit le nombre de fois qu'une ligne de code alloue ou libère de la mémoire.

Par exemple, dans la sortie ci-dessus, la ligne 11 s'est produite deux fois avec un incrément de mémoire de 0,1 MiB (Mebibyte), augmentant l'utilisation de la mémoire à 55,4 MiB. Les lignes 19 et 22 ont également contribué respectivement à 0,2 Mio et 0,3 Mio, totalisant l'utilisation de la mémoire à 55,9 Mio.

Trouver le profil de mémoire d'un script Python par horodatage

Vous pouvez également estimer le profil de mémoire d'un script Python entier à l'aide de la profil_mémoire en exécutant le mprof commande dans le terminal comme indiqué :

mprof exécuter nom_script.py

La commande ci-dessus échantillonne le script spécifié toutes les 0,1 s et crée automatiquement un .dat fichier dans votre répertoire de projet actuel.

Les chiffres qui suivent MÉM notation sont les profils d'utilisation de la mémoire du script Python à un intervalle de temps spécifique. Les derniers chiffres à droite représentent l'horodatage que le profileur a capturé pour chaque utilisation de la mémoire.

Vous pouvez également obtenir un tracé du profil de mémoire. Cela nécessite une installation de matplotlib:

pip installer matplotlib

Une fois installé, lancez le mprof commande comme ceci :

tracé mprof

Voici la sortie dans ce cas :

Exécutez le profil de mémoire de script dans un fichier Python dédié

Vous souhaiterez peut-être profiler différents scripts Python. Tu peux le faire en utilisant un module Python dédié via Python sous-processus.

De cette façon, vous pouvez séparer votre profileur de mémoire de votre base de code et enregistrer la sortie graphique localement :

importer sous-processus

sous-processus.run([
'mprof', 'courir', '--inclure-les-enfants', 'missing.py'
])

# enregistrer la sortie du tracé localement
sous-processus.run(['mprof', 'parcelle', '--sortie=sortie.jpg'])

Pour exécuter le profil de mémoire du script, il vous suffit d'exécuter le fichier Python contenant le code ci-dessus. Cela génère un tracé de profil de mémoire (sortie.jpg) dans le répertoire du fichier :

Trouver la quantité de mémoire utilisée à partir d'une exécution de fonction

Vous pouvez trouver le profil de mémoire total d'une méthode ou d'une fonction pendant l'exécution à l'aide de la psutil emballer.

Par exemple, pour dresser le profil du précédent Manipulation de Pandas DataFrame méthode dans un autre fichier Python :

importer psutil
importer système
importer os
sys.path.append (sys.path[0] + "/..")

# importez la classe contenant votre méthode
depuis uncode.manquant importer Manipuler

# instancie la classe
manip = Manipuler()

processus = psutil. Processus (os.getpid())
mémoire_initiale = process.memory_info().rss

# exécutez la méthode cible :
manip.manipulateData()

# obtenir les informations sur la mémoire après l'exécution
mémoire_finale = process.memory_info().rss
mémoire_consommée = mémoire_finale - mémoire_initiale
memory_consumed_mb = memory_consumed / (1024 * 1024)
imprimer(f"Mémoire consommée par la fonction: {memory_consumed_mb :.2F} Mo")

Ce qui précède estime le profil de mémoire total de la méthode en mégaoctets (Mo), comme indiqué :

Trouver le profil de mémoire d'une ligne de code dans Jupyter Notebook

Si vous utilisez iPython dans Jupyter Notebook, vous pouvez calculer le profil de mémoire d'un one-liner en utilisant le profil_mémoire. Il vous suffit de charger profil_mémoire dans une cellule. Ajoutez ensuite le %memit fonction magique à votre code dans les cellules suivantes; cela renvoie la mémoire maximale du code et sa taille incrémentée.

Cette méthode ne fonctionne pas avec les scripts Python réguliers en plus d'iPython dans Jupyter Notebook.

Par exemple:

Vous pouvez également utiliser le %memit fonction magique dans Jypyter Notebook pour profiler la mémoire d'une fonction lors de l'exécution :

Améliorez l'efficacité de votre mémoire dans votre code Python

Compte tenu des tâches lourdes de collecte de données pour lesquelles nous utilisons souvent Python, chaque ligne de code nécessite une optimisation adéquate pour gérer l'utilisation de la mémoire. Bien que Python comporte de nombreuses fonctions Python intégrées, les objets non référencés entraînent des fuites de mémoire.

Si vous avez supprimé toutes les syntaxes Python qui fonctionnent dans votre base de code sans tenir compte de l'utilisation de la mémoire, vous voudrez peut-être regarder en arrière avant d'aller trop loin.