Optimisez la vitesse et la mémoire de votre code Python avec __slots__
Qu'est-ce que __slots__ ?
TL;DR: __slots__
en Python est utilisé pour limiter les attributs qui peuvent être définis dans une classe.
__slots__
est un attribut de classe qui contient généralement des strings.
Lorsque __slots__
est défini dans une classe, les instances de cette classe ne peuvent avoir que les attributs spécifiés dans __slots__
.
L'utilisation de __slots__
peut être utile pour économiser de l'espace mémoire en limitant le nombre d'attributs d'une instance.
Par exemple, si une classe n'a besoin que de quelques attributs et que nous savons que nous n’aurons pas besoin d’ajouter des attributs de manière dynamique, il peut être avantageux de les spécifier dans __slots__
.
Une classe normale
Nous pouvons accéder à l’attribut __dict__
et également assigner un nouvel attribut dynamiquement sans soucis.
Une classe avec __slots__
Ici, nous avons défini __slots__
avec un tuple qui contient une string “x”, ce qui signifie que nos instances ne pourront avoir qu’un seul attribut qui s’appelle x. Avoir d’autres attributs est impossible.
Par exemple, en regardant la ligne 9, si l’on essaie d’assigner un autre attribut comme ce que nous avons fait dans l’autre classe nous allons obtenir une AttributeError.
De la même manière, comme nous l’avons expliqué, l’attribut __dict__
n’existe pas dans ce contexte et génère donc un AttributeError.
Si vous utilisez des dataclasses, vous pouvez également utiliser __slots__
facilement, et ceci aura le même effet que précédemment.
Si vous appréciez la newsletter StuffAndCode, vous pouvez vous inscrire afin de ne manquer aucun article !
🐍 Et recevez en PLUS, un article exclusif sur comment profiler n’importe quel type de code Python.
Mesurons les performances
Nous allons comparer deux scripts qui font la même chose.
La seule différence est que l’attribut “x” sera défini dans le __slots__
du deuxième script.
Voici notre premier script :
Et voici notre second script :
Si l’on décide de profiler avec cProfile nos scripts, nous obtenons ces résultats :
Nous pouvons constater un gain de performance de 1.24x plus rapide ou 23.53% plus rapide en spécifiant le __slots__
.
Mesurons la mémoire
Nous l’avons dit, un des intérets de __slots__
est surtout lorsque nous avons beaucoup d’instances de cet objet là.
Nous avons vu que c’était déjà bien plus rapide, mais qu’en est t-il de la mémoire que nous pouvons économiser ?
Pour ceci nous allons mesurer avec un profiler de mémoire appelé “filprofiler”.
Voici les résultats pour la version sans __slots__
Et voici les résultats avec __slots__
Le résultat est flagrant, nous avons donc une consommation de mémoire 1.82 fois moindre, soit une réduction de 54.8%, ce qui est assez énorme.
Il faut cependant se rappeler que dans ce cas précis nous avons 1 million d’instances. Ce qui peut potentiellement vous arriver en fonction de votre cas d’usage.
Si jamais vous avez peu d’instances, vous ne verrez pas un gain de performance aussi élevé que ce que nous avons obtenu.
Vous pouvez trouver plus de documentation ici.
Quizz Time
Allez, c’est parti pour quelques petites questions :
Quels sont les intérêts d’utiliser
__slots__
?Que met-on dans l’attribut de classe
__slots__
?Quand pouvons-nous profiter au maximum de l’utilisation de
__slots__
?Qu’avons nous utilisé pour profiler la mémoire ?
Si vous appréciez la newsletter StuffAndCode, vous pouvez vous inscrire afin de ne manquer aucun article !
🐍 Et recevez en PLUS, un article exclusif sur comment profiler n’importe quel type de code Python.