Mise en cache de méthode avec arguments en Ruby

La mise en cache de méthode permet une optimisation facile en évitant l’exécution répétée de code lorsque cela n’est pas nécessaire. La technique est détaillée dans cet article fonctionne pour les méthodes qui ne prennent pas de paramètres. Nous allons voir comment adapter cette technique aux méthodes acceptant les paramètres.

Si nous prenons la méthode suivante :

class MyObject
  def heavy_method(param)
    @heavy_method_cache ||= begin
      # Ici on fait les actions gourmandes en
      #   utilisant le paramètre `params'
    end
  end
end

Lors du premier appel de la méthode, le block begin...end est exécuté en utilisant la valeur du paramètre param, et la valeur résultante est stockée dans la variable d’instance @heavy_method_cache.
Mais lorsque la méthode est appelée de nouveau, la valeur enregistrée dans @heavy_method_cache est directement retournée, et ce, indépendamment de la valeur de param.

# Création d'instance
my_object = MyObject.new

# Premier appel de la méthode
#   le block begin...end est exécuté
my_object.heavy_method(8) 

# Appels suivants
#   le block begin...end n'est plus exécuté,
#   c'est la valeur du précédent appel qui est retourné
my_object.heavy_method(125)

Utilisation d’une table de hachage pour la mise en cache

Afin de régler ce problème nous allons définir @heavy_method_cache comme table de hachage, et y stocker le résultat de la méthode pour chacune des valeurs de params :

class MyObject
  def heavy_method(param)
    @heavy_method_cache ||= {}
    @heavy_method_cache[param] ||= begin
      # Ici on fait les actions gourmandes 
      #   en utilisant le paramètre `params'
    end
  end
end

La première ligne permet de définit @heavy_method_cache comme une nouvelle table de hachage, sauf si celle-ci existe déjà. Ensuite, on utilise l’opérateur d’affectation ||= comme nous l’avons fait précédemment, mais en stockant le résultat dans la table à l’index définit par la valeur de param.

# Création d'instance
my_object = MyObject.new

# Premier appel de la méthode
#   le block begin...end est exécuté
my_object.heavy_method(8) 

# Appel avec le même paramètre
#   le cache est retourné
my_object.heavy_method(8) 

# Appels avec un autre paramètre
#   le block begin...end est exécuté
my_object.heavy_method(125)
Newsletter

Publié par

Benj

Artisan du web à plusieurs facettes, du développement à la gestion de produits complexes en passant par le pilotage de projets internationaux.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

onze + dix-huit =