J'ai autour où p> Je veux mettre en cache le top 1000 tuples, disons de manière à ne pas interroger la base de données à chaque fois. P> Comment construire un cache LRU dans Python? Ou y a-t-il des solutions connues à cela? P> p> 6,00 000 entrées dans mongodub code> dans le format suivant:
4 Réponses :
Python 3.2 FuncTools CODE> comprend un Cache LRU . Vous pouvez facilement cerourir de Repo , vérifier si vous Doit-le ajuster pour travailler avec Python 2 (ne devrait pas être trop difficile - peut-être utiliser iTertools code> au lieu de certaines cométiches - Demandez si vous avez besoin d'aide) et être fait. Vous devez envelopper la question dans un appelable et vous assurer que cela dépend des arguments de la fonction (hachable), cependant. P>
Cela semble intéressant, mais comment je l'obtiens de repo ??? Je ne sais pas comment faire ça \
@learner: La voie la plus simple serait la plus simple du fichier que j'ai lié à.
J'ai essayé mais quand j'essaie d'importer des fonctions de fonctionnement, il jette une erreur >>> Importer FuncTools Traceback (dernier appel en dernier): fichier "
@learner: Ah, bien sûr. NonLocal CODE> est un nouveau mot-clé Python 3 pour prendre en charge la fermeture. Cela peut être imité avec un hack sale, mais travaillant et succinct. Je pense que je résout ce problème, mais un nouveau est apparu: il utilise Collections.OrderedDict code>, qui est uniquement inclus dans 2.7+. En outre, le code semble être cassé O.O (faire référence à ordonnéddic.move_to_end code> qui n'existe pas) ...
Une implémentation de commande ordonnée est disponible formulaire PYPI.PHYTHON.ORG/PYPI/OREDEREDDICT . Cache.MOVE_TO_END (touche) code> est facilement implémenté comme Cache [clé] = cache.pop (clé) code>. Le sale baccalauréat est d'initialiser hits code> et manque code> comme hits_misses = [0, 0] code> et remplacer hits code> avec hits_misses [0] code> et manque code> avec hits_misses [1] code>.
Outre la version incluse dans Python 3.2, il existe des recettes de cache LRU dans le Python Cookbook a> y compris ces par Python Core Developer Raymond Hettinger. P>
le Cache LRU dans Python3.3 a o (1) Insertion, suppression et recherche.
La conception utilise une liste d'entrées circulaire doublement liée (arrangée la plus ancienne au moins) et une table de hachage pour localiser des liens individuels. Les hits de cache utilisent la table de hachage pour trouver le lien correspondant et le déplacer à la tête de la liste. Cache Misses Supprimer la liaison la plus ancienne et créez un nouveau lien à la tête de la liste liée. P>
Voici une version simplifiée (mais rapide) dans 33 lignes de Python très basique (utilisant uniquement des opérations de dictionnaire simple et de liste) . Il fonctionne sur python2.0 et plus tard (ou pypy ou jython ou python3.x): p> à partir de Python 3.1, CommandéDict Le rend encore plus simple d'implémenter un cache LRU: P> from collections import OrderedDict
class LRU_Cache:
def __init__(self, original_function, maxsize=1024):
self.original_function = original_function
self.maxsize = maxsize
self.mapping = OrderedDict()
def __call__(self, *key):
mapping = self.mapping
try:
value = mapping[key]
mapping.move_to_end(key)
except KeyError:
value = self.original_function(*key)
if len(mapping) >= self.maxsize:
mapping.popitem(False)
mapping[key] = value
return value
Il y a aussi des backports de la version Python 3.3 de Lru_cache, telle que cette qui fonctionne sur python 2.7. Si vous êtes intéressé par deux couches de mise en cache (sinon mis en cache dans l'instance, il vérifiera un cache partagé) J'ai créé lru2cache Basé sur le Backport de Lru_Cache. P>