Maison  >  Article  >  interface Web  >  N'appelez jamais deux fois la même fonction (avec mémorisation)

N'appelez jamais deux fois la même fonction (avec mémorisation)

WBOY
WBOYoriginal
2024-07-31 07:42:121083parcourir

Never call the same function twice (with memoization)

Je viens donc de découvrir ce petit concept intéressant de mémorisation.

J'ai commencé à lire l'article à ce sujet et j'ai arrêté dès que j'ai compris l'idée.

Ensuite, j'ai décidé de trouver la solution simple par moi-même et de la manière dont je la comprends.

Si vous n'en avez jamais entendu parler, la mémorisation est le processus de stockage des résultats de l'exécution d'une fonction, vous pouvez donc les extraire d'un peu (ou pas) de cache la prochaine fois que vous exécuterez cette fonction avec les mêmes arguments.

En réalité cela peut être utile pour une fonction très consommatrice de ressources. Cela entraîne le coût de l'utilisation d'espace supplémentaire comme cache. Mais cela peut améliorer la vitesse de votre code et l'expérience des utilisateurs qui l'utilisent.

J'ai un peu joué avec le code JS et j'ai trouvé cette solution :

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
    if(!cache[fnKey]) {
      cache[fnKey] = fn(...args);
    }

    return cache[fnKey]
  };
}

Ensuite, vous pouvez l'exécuter comme ça :

function _add(x, y) {
  console.log("function runs", x, y);
  return x + y;
}

const add = memoize(_add)

add(42, 69)
add(10, 15)
add(10, 15)

Cela conduit à l'exécution de la fonction deux fois (appels 'add' n°1 et n°2). Le troisième appel « ajouter » utilisera le cache car c'est le même que l'appel n°2.

'function runs' 42 69
'function runs' 10 15

Vous pouvez voir que 'function runs' 10 15 n'est appelée qu'une seule fois. En effet, la deuxième fois que nous l'appelons, le cache est utilisé.

Maintenant, décomposons rapidement ce qui se passe ici.

Dans cet exemple, nous utilisons un mécanisme de fermeture pour stocker le cache.

const memoize = fn => {
  const cache = {}
  return () => {

  };
}

Cela nous permet de lancer l'argument "fn", qui est le roi du parti car c'est exactement la fonction avec laquelle nous voulons opérer, dans les portées et "d'écouter" chacune de ses exécutions.

Je l'ai vraiment écrit de la manière la plus simpliste et la plus naïve. Nous allons donc utiliser le nom de la fonction avec des arguments comme clés du cache, et les résultats de son exécution comme valeurs.

Cela signifie qu'exécuter :

add(2, 2)

Résultats en

// Our cache
{
  'add(2, 2)': 4
}

Valeur du cache.

Je sais que ce n'est peut-être pas exactement ainsi que cela devrait être fait "de la bonne manière". Mais l'idée de cet exercice et de l'article ne concerne pas la solution sûre et sans cas extrêmes, bien testée.

Il s'agit d'apprentissage et de mise en œuvre simple. À propos du concept. Je ne me concentre donc pas sur les détails de la mise en œuvre pour le moment.

Maintenant, nous trouvons d'abord la clé de l'appel de fonction :

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
  };
}

Nous l'utiliserons pour stocker les résultats de l'exécution de la fonction dans le cache.

Ensuite, nous vérifions si cette clé (fnKey) existe déjà. Sinon, nous définissons la clé avec sa valeur à la suite de l'exécution de la fonction passée.

Au final, nous renvoyons toujours le résultat du cache. Donc vraiment l'exécution de la fonction passée à la méthode memoize se termine toujours par la fermeture (dans l'objet "cache").

Nous opérons désormais uniquement avec cet objet :

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
    if(!cache[fnKey]) {
      cache[fnKey] = fn(...args);
    }

    return cache[fnKey]
  };
}

Et c'est tout.

Maintenant, je vais aller voir comment cela doit être fait "correctement". Mais si vous trouvez cela intéressant, faites-le-moi savoir. Si quelque chose n'est pas clair ou ne va pas avec cette approche (à votre goût), déposez simplement le commentaire et parlons-en.

Merci, à bientôt !

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:NodeJS + ROHCArticle suivant:NodeJS + ROHC