Maison  >  Article  >  développement back-end  >  Comment utiliser la bibliothèque de pooling d'objets universelle Python efficace

Comment utiliser la bibliothèque de pooling d'objets universelle Python efficace

WBOY
WBOYavant
2023-05-11 16:16:06804parcourir

Le mode pool d'objets est principalement adapté aux scénarios d'application suivants :
  • Scénarios avec des ressources limitées. Par exemple, dans un environnement qui ne nécessite pas d'évolutivité (les ressources physiques telles que le processeur et la mémoire sont limitées), les performances du processeur ne sont pas assez fortes, la mémoire est relativement limitée, le garbage collection et la gigue de la mémoire auront un impact relativement important, et l'efficacité de la gestion de la mémoire doit être améliorée. La réactivité est meilleure que le débit est plus important.

  • Un nombre limité d'objets en mémoire.

  • Des objets coûteux à créer.

  • Un grand nombre d'objets à courte durée de vie et à faible coût d'initialisation sont regroupés pour réduire les coûts d'allocation et de réallocation de mémoire et éviter la fragmentation de la mémoire.

  • Pour un langage dynamique comme Python, GC s'appuie sur une technologie de référence pour garantir que les objets ne seront pas recyclés prématurément. Dans certains scénarios, il peut y avoir une période d'inactivité pendant laquelle personne n'utilise l'objet même s'il est créé, ce qui entraîne. l'objet à recycler. Il peut être délégué au pool d’objets pour sa conservation.

Pond Introduction

Pond est un pool d'objets général efficace en Python, avec les caractéristiques de bonnes performances, une faible utilisation de la mémoire et un taux de réussite élevé. La possibilité de recycler automatiquement en fonction de la fréquence basée sur des statistiques approximatives permet d'ajuster automatiquement le nombre d'objets libres dans chaque pool d'objets.

Parce qu'actuellement Python ne dispose pas d'une meilleure bibliothèque de pooling d'objets avec des cas de test complets, des commentaires de code complets et une documentation complète. Dans le même temps, la bibliothèque de pooling d'objets grand public actuelle ne dispose pas d'un mécanisme de recyclage automatique intelligent.

Pond est peut-être la première bibliothèque de pooling d'objets en Python avec des cas de test complets divulgués par la communauté, un taux de couverture de plus de 90 %, des commentaires de code complets et une documentation complète.

Pond s'inspire d'Apache Commons Pool, Netty Recycler, HikariCP et Caffeine, intégrant les avantages de beaucoup d'entre eux.

Deuxièmement, Pond compte la fréquence d'utilisation de chaque pool d'objets dans un très petit espace mémoire en utilisant un comptage approximatif et le recycle automatiquement.

Lorsque le trafic est relativement aléatoire et moyen, la stratégie et le poids par défaut peuvent réduire l'utilisation de la mémoire de 48,85 % et le taux de réussite de l'emprunt est de 100 %.

Comment utiliser la bibliothèque de pooling dobjets universelle Python efficace

Lorsque le trafic est plus conforme à la loi 2/8, la stratégie et le poids par défaut peuvent réduire l'utilisation de la mémoire de 45,7 % et le taux de réussite de l'emprunt est de 100 %.

Comment utiliser la bibliothèque de pooling dobjets universelle Python efficace

Aperçu du design

Pond est principalement composé de FactoryDict, Counter, PooledObjectTree et d'un fil de recyclage séparé.

FactoryDict

L'utilisation de Pond nécessite la mise en œuvre de la fabrique d'objets PooledObjectFactory qui fournit la création, l'initialisation, la destruction, la vérification et d'autres opérations d'objets, et est appelée par Pond.

Ainsi, pour que le pool d'objets prenne en charge le stockage d'objets complètement différents, Pond utilise un dictionnaire pour enregistrer le nom de chaque classe d'usine et l'objet instancié de la classe d'usine qu'il implémente.

Chaque PooledObjectFactory doit avoir les quatre fonctions de création d'objets, de destruction d'objets, de vérification si les objets sont toujours disponibles et de réinitialisation des objets.

Ce qui est spécial, c'est que Pond prend en charge la réinitialisation automatique des objets, car dans certains scénarios, il peut y avoir des situations où l'objet doit d'abord se voir attribuer une valeur et être transmis, puis être recyclé après avoir été transmis afin d'éviter toute contamination. Il est recommandé d'implémenter cette fonction dans de tels scénarios.

Counter

Counter stocke un compteur approximatif.

PooledObjectTree

PooleedObjectTree est un dictionnaire Chaque clé correspond à une file d'attente premier entré, premier sorti.

Chaque file d'attente contient plusieurs PooleedObjects. PooledObject enregistre l'heure de création, l'heure du dernier prêt et l'objet réellement requis.

Sécurité des fils

L'emprunt et le recyclage de Pond sont tous deux sans danger pour les fils. Le module de file d'attente de Python fournit une structure de données premier entré, premier sorti (FIFO) adaptée à la programmation multithread. Il peut être utilisé pour transmettre en toute sécurité des messages ou d’autres données entre les threads producteur et consommateur.

Le verrou est géré par l'appelant et tous les threads multiples peuvent fonctionner en toute sécurité et facilement en utilisant la même instance de file d'attente. L'emprunt et le recyclage de Pond fonctionnent tous deux sur la file d'attente, ils peuvent donc fondamentalement être considérés comme thread-safe.

Mécanisme de prêt

Lorsque vous utilisez Pond pour prêter un objet, il vérifiera d'abord si le type d'objet que vous souhaitez prêter existe déjà dans PooledObjectTree. S'il existe, il vérifiera si le pool d'objets de cet objet est vide. Si tel est le cas, Empty en créera un nouveau.

S'il y a des objets en excès dans le pool d'objets, la file d'attente sera utilisée pour faire apparaître un objet et vérifier si cet objet est disponible. S'il n'est pas disponible, la Factory correspondante sera automatiquement appelée pour nettoyer et détruire l'objet. En même temps, son compte GC en Python sera effacé, afin qu'il puisse être recyclé par GC plus rapidement, et le suivant sera pris. en continu jusqu'à ce qu'il y en ait un disponible.

Si cet objet est disponible, il sera restitué directement. Bien entendu, qu'un objet soit retiré du pool d'objets ou qu'un nouvel objet soit créé, Counter sera utilisé pour incrémenter un décompte.

Mécanisme de recyclage

Lors du recyclage d'un objet, il déterminera si le pool d'objets cible existe. S'il existe, il vérifiera si le pool d'objets est plein. S'il est plein, l'objet à restituer sera automatiquement détruit.

Ensuite, il vérifiera si l'objet a été prêté trop longtemps. S'il dépasse la durée maximale configurée, il sera également effacé.

Recyclage automatique

Le recyclage automatique sera exécuté de temps en temps, la valeur par défaut est de 300 s. Nettoyez automatiquement les objets du pool d'objets qui ne sont pas fréquemment utilisés.

Instructions

Vous pouvez d'abord installer la bibliothèque Pond et la référencer dans votre projet.

pip install pondpond
from pond import Pond, PooledObjectFactory, PooledObject

Vous devez d'abord déclarer une classe d'usine pour le type d'objet que vous souhaitez insérer. Par exemple, dans l'exemple ci-dessous, nous voulons que l'objet regroupé soit Dog, nous déclarons donc d'abord une classe PooledDogFactory et implémentons PooledObjectFactory.

class Dog:
 name: str
 validate_result:bool = True
class PooledDogFactory(PooledObjectFactory):
 def creatInstantce(self) -> PooledObject:
 dog = Dog()
 dog.name = "puppy"
 return PooledObject(dog)
 def destroy(self, pooled_object: PooledObject):
 del pooled_object
 def reset(self, pooled_object: PooledObject) -> PooledObject:
 pooled_object.keeped_object.name = "puppy"
 return pooled_object
 def validate(self, pooled_object: PooledObject) -> bool:
 return pooled_object.keeped_object.validate_result

Ensuite, vous devez créer l'objet Pond :

pond = Pond(borrowed_timeout=2,
 time_between_eviction_runs=-1,
 thread_daemon=True,
 eviction_weight=0.8)

Pond peut transmettre certains paramètres, qui représentent :

borrowed_timeout : l'unité est la seconde, la période maximale de l'objet prêté, l'objet qui dépasse la période sera sera automatiquement détruit une fois retourné. Ne sera pas mis dans le pool d'objets.

time_between_eviction_runs : L'unité est la seconde, l'intervalle entre le recyclage automatique.

thread_daemon : thread démon, si True, le thread automatiquement recyclé sera fermé lorsque le thread principal sera fermé.

eviction_weight : Le poids lors du recyclage automatique sera multiplié par la fréquence d'utilisation maximale. Les objets du pool d'objets dont la fréquence d'utilisation est inférieure à cette valeur entreront dans l'étape de nettoyage.

Classe d'usine instanciée :

factory = PooledDogFactory(pooled_maxsize=10, least_one=False)

Tout ce qui hérite de PooledObjectFactory aura son propre constructeur qui peut transmettre les paramètres pooled_maxsize et least_one.

pooled_maxsize : Le nombre maximum d'objets pouvant être placés dans le pool d'objets généré par cette classe d'usine.

least_one : Si True, lors du nettoyage automatique, le pool d'objets générés par cette classe d'usine conservera au moins un objet.

Enregistrez cet objet d'usine auprès de Pond. Par défaut, le nom de classe de l'usine sera utilisé comme clé de PooledObjectTree :

pond.register(factory)

Bien sûr, vous pouvez également personnaliser son nom, et le nom sera utilisé comme nom. clé de PooledObjectTree :

pond.register(factory, name="PuppyFactory")

Après un enregistrement réussi, Pond commencera automatiquement à créer des objets en fonction de la taille pooled_maxsize définie en usine jusqu'à ce que le pool d'objets soit rempli.

Emprunter et rendre des objets :

pooled_object: PooledObject = pond.borrow(factory)
dog: Dog = pooled_object.use()
pond.recycle(pooled_object, factory)

Bien sûr, vous pouvez emprunter et rendre des objets par leur nom :

pooled_object: PooledObject = pond.borrow(name="PuppyFactory")
dog: Dog = pooled_object.use()
pond.recycle(pooled_object, name="PuppyFactory")

Effacer complètement un pool d'objets :

pond.clear(factory)

Nettoyer un pool d'objets par son nom :

pond.clear(name="PuppyFactory")

Normalement, vous uniquement Vous devez utiliser les méthodes ci-dessus, et la génération et le recyclage d'objets sont entièrement automatiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer