Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use `withMutations` on a map in Immutable.js?

Tags:

immutable.js

I have a series of mutations to make on my Immutable.js map.

At what point should I prefer using withMutations rather than creating intermediate immutable maps?

From the Immutable.js docs:

If you need to apply a series of mutations to produce a new immutable Map, withMutations() creates a temporary mutable copy of the Map which can apply mutations in a highly performant manner. In fact, this is exactly how complex mutations like merge are done.

But, where is the line? If I need to make two mutations should I use withMutations?

like image 332
dstreit Avatar asked Feb 13 '15 23:02

dstreit


People also ask

Are maps immutable JavaScript?

js provides many Persistent Immutable data structures including: List , Stack , Map , OrderedMap , Set , OrderedSet and Record .

What is a map in immutable js?

An Immutable Map is an unordered collection of key/value pairs that at first glance seems similar to a JavaScript object. However, it has the following additional properties: You can iterate over the keys of a Map.

Should I use immutable js?

Using ImmutableJS can improve dramatically the performance of your application. And, because the immutable data never changes, you can always expect new data to be passed from the above. To make sure you are correctly comparing the data and not updating the UI when there is no change, you should always use the .

Is map function immutable?

Multiple iterations of the same Map will iterate in the same order. Map's keys can be of any type, and use Immutable.is to determine key equality.


2 Answers

You should use withMutations when you want to group several changes on an object.

Because each change creates a clone, several changes in a row cause several clones. Use withMutations to apply several changes then clone once at the end. A clone at every step means that you are reading the entire list for each change, which makes it an n^2 operation. Using the mutatable version leaves it at just N.

This can create a massive performance hit if you just start doing things willy nilly like the other answer suggests. The kicker is it might not matter on a small test of data, but what happens if you push it live and then do a large scale operation on an array with 300,000 pieces of data instead of your test data which only has 100 elements. In your test data, you did 10,000 copies of which you might not notice. In production you would do 900,000,000,00 copies which might light your computer on fire (not really, but you would freeze the tab).

I wrote a demo demonstrating the performance difference http://jsperf.com/with-out-mutatable

like image 95
Eric Wooley Avatar answered Oct 05 '22 11:10

Eric Wooley


I've also been trying to decide when it's best to use withMutations vs not. So far I have always been using withMutations when I need to loop through a list of items with unknown size n, and perform n mutations on a single map. Example:

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

What I wanted to know, is if I should use withMutations on a smaller known set of updates, or if I should just chain set.

Example:

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

Or:

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

In this case, I would prefer to use the first option (chained set calls), but I wasn't sure of the performance impact. I created this jsPerf to test some similar cases: http://jsperf.com/immutable-batch-updates-with-mutations.

I ran batches of 2 updates and 100 updates, using an empty inital map, and a complex initial map, both using withMutations and just chaining set.

The results seem to show that withMutations was always better on the 100 update case, regardless of initial map. withMutations performed marginally better on the 2 update case when starting with an empty map. However, just chaining 2 set calls performed better when starting with a complex map.

like image 24
Wade Peterson Avatar answered Oct 05 '22 10:10

Wade Peterson