Lors de l'utilisation de memoization dans Ruby on Rails
À la mi-juillet 2008 Memoization a été ajouté à Rails de base. Une démonstration de l'utilisation est ici.
Je n'ai pas été en mesure de trouver les bons exemples en la matière lorsque les méthodes doivent être memoized, et les implications sur les performances de chacun. Ce blog, par exemple, suggère que, souvent, memoization ne doit pas être utilisé à tous.
Pour quelque chose qui pourrait avoir d'énormes implications sur les performances, il semble y avoir peu de ressources qui vont au-delà de la fourniture d'un tutoriel simple.
Quelqu'un a vu memoization utilisés dans leurs propres projets? Quels sont les facteurs qui vous ferait considérer memoizing une méthode?
Après avoir fait un peu plus de recherche sur mon propre j'ai trouvé que memoization est utilisé dans un grand nombre de fois à l'intérieur des Rails de base.
Voici un exemple: http://github.com/rails/rails/blob/1182658e767d2db4a46faed35f0b1075c5dd9a88/actionpack/lib/action_view/template.rb.
Cette utilisation semble aller à l'encontre des conclusions du blog ci-dessus qui a trouvé memoization peut nuire à la performance.
Vous devez vous connecter pour publier un commentaire.
Je pense que beaucoup de développeurs web ne comprennent pas pleinement ce que memoization fait et comment il fonctionne. Je l'ai vu pour des méthodes qui retournent des paresseux chargé des collections (comme une Suite dataset), ou pour des méthodes qui ne prennent pas des arguments mais des calculs basés sur des variables d'instance. Dans le premier cas, la memoization n'est rien, mais les frais généraux, et dans le second, elle est aussi une source de méchant et dur pour traquer les bugs.
Je pas appliquer memoization si
Il existe d'autres situations où des memoization n'est pas appropriée, telle que celle de la question et les réponses ci-dessus, mais ce sont les trois qui je pense ne sont pas aussi évidente.
Le dernier élément est sans doute le plus important: memoization caches un résultat basé sur les arguments de la méthode, si la méthode ressemble à ce qu'il ne peut pas être memoized:
Les deux peuvent, toutefois, être réécrit pour tirer parti de memoization (bien que, dans ces deux cas, il ne devrait évidemment pas être fait pour d'autres raisons):
(en supposant que
find_by_shoe_size
n'ont pas, ou invoqué, tous les effets secondaires)L'astuce consiste à extraire une pure fonction de la méthode et de l'appliquer memoization à la place.
def self.active @active_cities =|| where("cities.active = (?)", true) end
Lorsque de nouvelles villes sont ajoutés de temps en temps à la base de données par les administrateurs lorsque l'application est en direct, aurais-je besoin de redémarrer le serveur pour remplacer ce memoized variable d'instance? Ou un memoized variable d'instance se détruit et recréé après chaque requête?Lorsqu'une méthode récupère des données à partir de plusieurs tables, et d'effectuer quelques calculs avant de retourner l'objet, et cette méthode est à de multiples reprises des demandes, memoization peut avoir du sens.
Rappelez-vous que la mise en cache de requêtes est également active, de sorte que seule memoize méthodes qui effectuent Ruby calculs, pas de pur extrait de la base de données.
Peut-être que mon expérience est un bon exemple de quand ne PAS utiliser memoize. Dans mon modèle, j'ai été memoizing à la fois simple des résultats de calcul, c'est à dire le n ° d'Ordre sous-total, le n ° d'Ordre fiscal; ainsi que des objets de modèle, c'est à dire le n ° d'Ordre most_recent_credit_card_used. Dans ce dernier, lors de la memoizing une méthode qui retourne une Carte de crédit en objet, je voudrais obtenir de "gelée de hachage' erreur lors de la tentative de mise à jour des attributs sur l'memoized objet. N ° d'ordre most_recent_credit_card_used.est-il bloqué? renvoyé true lorsque la méthode a été memoized, ce qui, évidemment, n'est pas ce que je désirais.
Mon take-away est simple: utiliser memoize pour des opérations coûteuses qui retournent des types de données simples (entiers, flotteurs, etc.) mais Ne l'utilisez Pas memoize lors du retour des objets complexes comme ActiveRecord modèles, esp. si vous avez l'intention de mettre à jour les objets en mémoire.