Comment puis-je le profil d'utilisation de la mémoire en Python?
J'ai récemment intéressé à des algorithmes et ont commencé à explorer par la rédaction d'un naïf mise en œuvre et l'optimisation de différentes manières.
Je suis déjà familier avec la norme module Python pour le profilage d'exécution (pour la plupart des choses que j'ai trouvé le timeit fonction magique dans IPython être suffisant), mais je suis aussi intéressé par l'utilisation de la mémoire afin que je puisse explorer les inconvénients (p. ex. le coût de la mise en cache d'une table de valeurs précédemment calculées rapport à recalculer si nécessaire). Est-il un module qui sera le profil de l'utilisation de la mémoire d'une fonction donnée pour moi?
Vous devez vous connecter pour publier un commentaire.
Celui-ci a été déjà répondu ici: Python memory profiler
Fondamentalement, vous faites quelque chose comme ça (cité de l' Guppy-PE):
Python 3.4 inclut un nouveau module:
tracemalloc
. Il fournit des statistiques détaillées sur le code qui est d'allouer le plus de mémoire. Voici un exemple qui affiche les trois premières lignes de l'allocation de mémoire.Et voici les résultats:
Quand est-ce une fuite de mémoire pas une fuite?
Cet exemple est grande lorsque la mémoire est toujours détenu à la fin du calcul, mais parfois vous avez le code qui alloue beaucoup de mémoire et puis il libère tous. Il n'est pas techniquement une fuite de mémoire, mais il utilise plus de mémoire que vous pensez qu'il devrait. Comment pouvez-vous suivre l'utilisation de la mémoire lorsque tout cela est sorti? Si c'est votre code, vous pouvez probablement ajouter un peu de débogage de code pour prendre des captures d'écran en cours d'exécution. Si non, vous pouvez démarrer un thread d'arrière-plan pour surveiller l'utilisation de la mémoire lorsque le thread principal s'exécute.
Voici l'exemple précédent où le code a été déplacé dans le
count_prefixes()
fonction. Lorsque cette fonction renvoie la, tous les la mémoire est libérée. J'ai aussi ajouté quelquessleep()
appels à simuler un long calcul.Quand je lance cette version, l'utilisation de la mémoire a disparu à partir de 6 mo de descendre à moins de 4 ko, parce que la fonction a publié l'ensemble de ses de mémoire quand il a fini.
Maintenant, voici une version inspirée par une autre réponse qui commence un deuxième thread pour surveiller l'utilisation de la mémoire.
La
resource
module vous permet de vérifier l'utilisation courante de la mémoire, et enregistrer la capture de la crête de l'utilisation de la mémoire. La file d'attente permet au thread principal raconter la mémoire thread de contrôle lors de l'impression du rapport et de l'éteindre. Quand il est exécuté, il affiche la mémoire utilisée par lelist()
appel:Si vous êtes sous Linux, vous pouvez trouver
/proc/self/statm
plus utile que leresource
module.long_running()
à l'intérieur de lacount_prefixes()
fonction, le max RSS valeurs ne seront pas imprimées jusqu'à ce quelong_running()
retourne. Ou je me trompe?memory_monitor()
est en cours d'exécution sur un thread séparé decount_prefixes()
, de sorte que les seuls moyens que l'on peut avoir sur les autres sont le GIL et le message de la file d'attente que je passe àmemory_monitor()
. Je soupçonne que lorsquecount_prefixes()
appelssleep()
, il encourage le contexte du thread pour passer. Si votrelong_running()
n'est en fait pas prendre très longtemps, puis le contexte du thread pourrait ne pas switch jusqu'à ce que vous frappez lasleep()
de retour d'appel danscount_prefixes()
. Si cela ne fait pas sens, poser une nouvelle question et un lien à partir d'ici.Une approche simple à essayer:
Il suffit d'insérer
using("Label")
où vous voulez voir ce qu'il se passe.usage[2]
vous êtes à la recherche àru_maxrss
, qui n'est que la partie du processus qui est resident. Ce n'aidera pas beaucoup si le processus a été échangé sur le disque, même partiellement.resource
est un Unix module spécifique qui ne fonctionne pas sous Windows.ru_maxrss
(qui est,usage[2]
) sont ko, pas de pages, donc il n'est pas nécessaire de multiplier ce nombre parresource.getpagesize()
.Si vous souhaitez uniquement regarder l'utilisation de la mémoire d'un objet, (répondre aux questions des autres)
pymples
. Bien sûr, c'est "étrange"asizeof
asizeof
peut contribuer à la RSS, oui. Je ne suis pas sûr de ce que vous voulez dire par "liés".tracemalloc
solution ci-dessous une grandeur plus rapideDepuis la accepté de répondre et aussi le meilleur voté réponse, à mon avis, certains problèmes, j'aimerais apporter une réponse de plus que repose étroitement sur Ihor B. réponse avec quelques petites mais importantes modifications.
Cette solution vous permet d'exécuter de profilage sur soit en l'enveloppant d'un appel de fonction avec la
profile
de la fonction et de l'appeler, ou par la décoration de votre fonction/méthode avec le@profile
décorateur.La première technique est utile lorsque vous souhaitez le profil de certains de la troisième partie du code sans toucher à sa source, alors que la deuxième technique est un peu plus "propre" et fonctionne mieux lorsque vous n'avez pas l'esprit de la modification du code source de la fonction/méthode que vous voulez de profil.
J'ai aussi modifié la sortie, de sorte que vous obtenez RSS, VMS, et la mémoire partagée. Je ne se soucient pas beaucoup sur le "avant" et "après" valeurs", mais seulement le delta, donc j'ai enlevé ceux (si vous êtes à la comparant à Ihor B. la réponse).
Le profilage de code
Exemple d'utilisation, en supposant que le code ci-dessus est enregistré en tant que
profile.py
:Cela devrait se traduire par une sortie similaire à celle ci-dessous:
Quelques notes finales:
montrer jusqu'à zéro de la mémoire. Je suppose que c'est une limitation de
le matériel/OS (testé sur la base de l'ordinateur portable avec Linux) sur la façon dont souvent
de mémoire les statistiques sont mises à jour.
profile(my_function, arg)
de profilmy_function(arg)
peut-être l'aider à:
<voir plus d'>
Ci-dessous est une fonction simple décorateur qui permet de suivre la quantité de mémoire le processus consommé avant l'appel de la fonction, après l'appel de la fonction, et quelle est la différence:
Voici mon blog qui décrit tous les détails. (archivé lien)
process.memory_info().rss
pasprocess.get_memory_info().rss
, au moins dans ubuntu et python 3.6. connexes stackoverflow.com/questions/41012058/psutil-error-on-macos