web-dev-qa-db-fra.com

Comment réduire Python Utilisation de la mémoire de script

J'ai un très grand python, 200K, que j'aimerais utiliser le moins de mémoire possible. Il ressemble à quelque chose comme:

# a lot of data structures
r = [34, 78, 43, 12, 99]

# a lot of functions that I use all the time
def func1(Word):
    return len(Word) + 2

# a lot of functions that I rarely use
def func1(Word):
    return len(Word) + 2


# my main loop
while 1:
   # lots of code
   # calls functions

Si je mets les fonctions que j'utilise rarement dans un module, et les importe dynamiquement seulement si nécessaire, je ne peux pas accéder aux données. C'est aussi loin que je suis arrivé.

Je suis nouveau sur python.

Quelqu'un peut-il me mettre sur la bonne voie? Comment puis-je décomposer ce gros script afin qu'il utilise moins de mémoire? Vaut-il la peine de mettre du code rarement utilisé dans les modules et de ne les appeler qu'en cas de besoin?

24
Coo Jinx

Organisation:

Votre script python semble en effet énorme, peut-être devriez-vous envisager de réorganiser votre code d'abord, pour le diviser en plusieurs modules ou packages . Cela facilitera probablement le code le profilage et les tâches d'optimisation.

Vous voudrez peut-être y jeter un œil:

Et éventuellement:

Optimisation:

Il y a beaucoup de choses qui peuvent être faites pour optimiser votre code ...

Par exemple, en ce qui concerne vos structures de données ... Si vous faites un grand usage de listes ou de listes de listes, vous pouvez essayer de savoir où avez-vous vraiment besoin de listes, et où elles pourraient être remplacées par des structures de données non mutables comme des tuples ou par des objets "volatils", des conteneurs "paresseux", comme des expressions génératrices.

Voir:

Sur ces pages, vous trouverez des informations et des conseils utiles:

En outre, vous devriez étudier vos façons de faire et vous demander s'il existe un moyen de le faire moins avidement, un moyen qu'il est préférable de le faire dans Python (vous trouverez quelques conseils dans le tag Pythonic ) ... Cela est particulièrement vrai en Python, car en Python, il existe souvent une façon "évidente" (et une seule) de faire des choses qui sont meilleures que les autres (voir Le Zen de Python ), qui serait Pythonique . Ce n'est pas spécialement lié à la forme de votre code, mais aussi - et surtout - aux performances. Contrairement à beaucoup de langages, qui promeuvent l'idée qu'il devrait y avoir plusieurs façons de faire quoi que ce soit, Python préfère se concentrer sur le meilleur Donc, évidemment, il y a plusieurs façons de faire quelque chose, mais souvent, on est vraiment meilleur.

Maintenant, vous devez également vérifier si vous utilisez les meilleures méthodes pour faire les choses, car la pythonicalité n'organisera pas vos algorithmes pour vous.

Mais enfin, c'est très dépendant de votre code auquel il est difficile de répondre sans l'avoir vu.

Et assurez-vous de prendre en compte les commentaires de eumiro et Amr .

36
cedbeu

Cette vidéo pourrait vous donner de bonnes idées: http://pyvideo.org/video/451/pycon-2011---quot-dude--where--39-s-my-ram--quot-

4
Bryce

Les conseils sur les expressions de générateur et l'utilisation des modules sont bons. L'optimisation prématurée cause des problèmes, mais vous devez toujours passer quelques minutes à réfléchir à votre conception avant de vous asseoir pour écrire du code. Surtout si ce code est destiné à être réutilisé.

Soit dit en passant, vous mentionnez que de nombreuses structures de données sont définies en haut de votre script, ce qui implique qu'elles sont toutes chargées en mémoire au début. S'il s'agit d'un très grand ensemble de données, envisagez de déplacer des ensembles de données spécifiques vers des fichiers séparés et de le charger uniquement si nécessaire. (en utilisant le module csv, ou numpy.loadtxt(), etc.)

Indépendamment de l'utilisation de moins de mémoire, étudiez également les moyens d'utiliser la mémoire plus efficacement. Par exemple, pour les grands ensembles de données numériques, les tableaux numpy sont un moyen de stocker des informations qui fourniront de meilleures performances dans vos calculs. Il y a quelques conseils légèrement datés sur http://wiki.python.org/moin/PythonSpeed/PerformanceTips

3
abought

Le déplacement des fonctions ne changera pas votre utilisation de la mémoire. Dès que vous importez cet autre module, il définira toutes les fonctions du module. Mais les fonctions ne prennent pas beaucoup de mémoire. Sont-ils extrêmement répétitifs, peut-être pouvez-vous avoir moins de code en refactorisant les fonctions?

@ eumiro a une bonne question: êtes-vous sûr que votre script utilise trop de mémoire? Combien de mémoire utilise-t-il et pourquoi est-ce trop?

2
Ned Batchelder

Si vous profitez de OOP et que vous avez des objets, dites:

class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

Vous pouvez faire en sorte que l'objet occupe moins de mémoire en insérant:

__slots__ = ("lorem", "ipsum")

juste avant le __init__ fonction, comme indiqué:

class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

Bien sûr, "l'optimisation prématurée est la racine de tout mal". Faites également le profil de l'utilisation de mem avant et après l'ajout pour voir s'il fait réellement quelque chose. Méfiez-vous de casser du code (de façon sournoise), étant entendu que cela pourrait ne pas fonctionner.

0