born2net
born2net

Reputation: 24973

Compare & contrast redux reselect vs lodash / underscore memoize...?

I was wondering if someone can compare & contrast the differences between redux reselect lib vs lodash memoize...?

Upvotes: 7

Views: 2367

Answers (2)

Michael Liquori
Michael Liquori

Reputation: 629

There are 2 major differences:

  1. are all parameters checked for changes before recomputing, or just the first one?
  2. are all results cached, or only the most recent result?

lodash _.memoize:

  • only checks the first parameter for changes and returns the most recent result for that first parameter, regardless of whether other parameters have changed (by default).
  • keeps an infinitely large record of all result values keyed by that first parameter.

Example of a problematic case with lodash _.memoize:

const memoizedFunc = _.memoize(
    (param1, param2) => param1 + param2
);

console.log(memoizedFunc(1, 2)); // 3
console.log(memoizedFunc(1, 3)); // 3 (but it should be 4!)

Note that you can write a custom resolver function and pass it in as the second argument to _.memoize to change this behavior and thus take all or some parameters into account. This is extra logic to test and maintain and may or may not be worth it to you. (The resolver function determines the key to be used in the Map of cached results that the memoized function maintains. By default the key is just set to equal the first parameter.)

reselect:

  • checks all parameters for equality against the most recent execution only.
  • only caches a single result (the most recent).

Note that reselect is primarily used for redux applications, creating memoized selectors with createSelector. In createSelector, each parameter is expected to have a getter (selector) function, because of the expectation of usage with a redux store. If you are not trying to memoize data from a redux store, you still could use this and send in an identity function like _.identity for each parameter, but that would be silly.

Fortunately, if you only want to memoize functions, and you want all parameters checked for changes, you can use reselect's defaultMemoize and get the desired behavior.

Summary / other libraries (memoize-one)

If you want all parameters checked for changes, and are not using redux or otherwise need to use createSelector, you may want to just use a very lightweight and fast library intended for specifically for this like memoize-one.

If you do want createSelector, you can just use reselect for all your needs most likely.

If you want all results to be cached, not just the most recent ones, you can use lodash _.memoize alone, and you can also customize reselect to use that feature of lodash _.memoize.

Upvotes: 7

Andrea Carraro
Andrea Carraro

Reputation: 10419

Lodash's memoize is a classic memoizing utility: It memoizes a function using (by default) its first argument as cache key. Lodash's memoize keeps track/caches all the results obtained with different cache keys.

Reselect instead, checks each provided argument, and (by default) recomputes the result ONLY IF one of the arguments changes. Reselect's selectors have by default a cache size of 1, and are mainly designed to stabilize state-derived data avoiding undesired recomputations.

Upvotes: 7

Related Questions