web-dev-qa-db-fra.com

Quand dois-je utiliser `withMutations` sur une carte dans Immutable.js?

J'ai une série de mutations à faire sur ma carte Immutable.js.

À quel moment dois-je préférer utiliser withMutations plutôt que de créer des cartes intermédiaires immuables?

À partir des documents Immutable.js:

Si vous devez appliquer une série de mutations pour produire une nouvelle carte immuable, withMutations () crée une copie mutable temporaire de la carte qui peut appliquer des mutations de manière très performante. En fait, c'est exactement ainsi que se font les mutations complexes comme la fusion.

Mais où est la ligne? Si j'ai besoin de faire deux mutations, dois-je utiliser withMutations?

29
dstreit

Vous devez utiliser withMutations lorsque vous souhaitez regrouper plusieurs modifications sur un objet.

Étant donné que chaque modification crée un clone, plusieurs modifications consécutives provoquent plusieurs clones. Utilisez withMutations pour appliquer plusieurs modifications, puis clonez une fois à la fin. Un clone à chaque étape signifie que vous lisez la liste entière pour chaque modification, ce qui en fait une opération n ^ 2. L'utilisation de la version modifiable la laisse juste N.

Cela peut créer un énorme impact sur les performances si vous commencez à faire les choses comme bon vous semble, comme le suggère l'autre réponse. Le kicker est que cela peut ne pas avoir d'importance sur un petit test de données, mais que se passe-t-il si vous le poussez en direct et effectuez ensuite une opération à grande échelle sur un tableau avec 300000 éléments de données au lieu de vos données de test qui ne contiennent que 100 éléments. Dans vos données de test, vous avez fait 10 000 copies dont vous ne remarquerez peut-être pas. En production, vous feriez 900 000 000 000 copies qui pourraient allumer votre ordinateur en feu (pas vraiment, mais vous gèleriez l'onglet).

J'ai écrit une démo démontrant la différence de performance http://jsperf.com/with-out-mutatable

26
Eric Wooley

J'ai également essayé de décider quand il était préférable d'utiliser withMutations vs not. Jusqu'à présent, j'ai toujours utilisé withMutations lorsque j'ai besoin de parcourir une liste d'éléments de taille inconnue n et d'effectuer des mutations n sur une seule carte. Exemple:

updateItems(state, items) {
    return state.withMutations(state => {
        items.forEach(item => {
            state.set(item.get('id'), item);
         });
    });
}

Ce que je voulais savoir, c'est si je devais utiliser withMutations sur un plus petit ensemble de mises à jour connues, ou si je devais simplement chaîner set.

Exemple:

setItems(state, items, paging) {
    return state.set('items', items).set('paging', paging);
}

Ou:

setItems(state, items, paging) {
    return state.withMutations(state => {
        state.set('items', items);
        state.set('paging', paging);
    });
}

Dans ce cas, je préférerais utiliser la première option (appels chaînés set), mais je n'étais pas sûr de l'impact sur les performances. J'ai créé ce jsPerf pour tester des cas similaires: http://jsperf.com/immutable-batch-updates-with-mutations .

J'ai exécuté des lots de 2 mises à jour et 100 mises à jour, en utilisant une carte initiale vide et une carte initiale complexe, utilisant à la fois withMutations et simplement chaînant set.

Les résultats semblent montrer que withMutations était toujours meilleur dans le cas de la mise à jour 100, quelle que soit la carte initiale. withMutations a légèrement amélioré la mise à jour 2 lors du démarrage avec une carte vide. Cependant, le simple chaînage de 2 appels set a donné de meilleurs résultats lors du démarrage d'une carte complexe.

12
Wade Peterson

Je voudrais simplement créer des cartes immuables intermédiaires, puis utiliser des outils de profilage pour vérifier si vous avez réellement des problèmes de performances avec cette approche. Pas besoin de faire des optimisations de performances avant d'avoir des problèmes de performances.

En règle générale, je préfère utiliser des fonctionnalités existantes telles que .map, .filter etc. sans penser à withMutations. S'il est nécessaire de créer une nouvelle liste (ou carte) où chaque élément est muté, je remettrais d'abord en question ce besoin et j'essaierais de résoudre le problème en utilisant les outils existants et le style de programmation fonctionnel. Si cela est impossible, je créerais une mutation personnalisée avec withMutations.

2
OlliM