Recoil: using selectorFamily in a loop is slow

Hello I’m experiencing a weird performance issue regarding atomFamily and selectorFamily when used with big collections. Here is my code:

const resourcesByIdAtom = atomFamily({ key: "resourcesByIdAtom", default: initialState })

const resourceState = selectorFamily({
  key: "resourceState",
  get: (id) => ({ get }) => get(resourcesByIdAtom(id))
})

const resourcesState = selectorFamily({
  key: "resourcesState",
  get: ids => ({ get }) => {
    return ids.map(id => get(resourceState(id)))
  },
})

const useResourcesValue = ids => useRecoilValue(resourcesState(ids))

The idea is that we fetch and keep a lot of resources inside this atom resourcesByIdAtom, and we are using atomFamily in order to be able to access them also directly, based on their id. But, there is a case we need to pass a lot of ids directly and read the data for all of them.

So using useResourcesValue with a big array of ids, it takes a lot of time to calculate, cpu is on 100% and the main thread is completely bloated.

Is there any suggestions? Am I doing something completely wrong?

I’d expect selectors, especially for something that haven’t change to be super fast.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 9
  • Comments: 19 (7 by maintainers)

Commits related to this issue

Most upvoted comments

After some digging I found that the mergeDependencyMapIntoGraph function will be called every time a get operation in the selector is called, and the size of deps , which will be iterated, grows as the number of get function calls, hence as we call more get in the selector, the function becomes exponentially slower. Any thoughts on this? I assume this is here for a reason and is there any ways we can improve that? @drarmstr

I’m probably not going to code it up, but a selector might be used to aggregate the total cost of items in an order. In that case you would have an atom of order, an atom family of products, and a selector for the totals. If the number of products ordered gets high that’s where the system breaks down. Not sure if this is a really realistic example though.

On Thu, May 6, 2021 at 4:57 PM Johnny Klironomos @.***> wrote:

No reason, since this is just a simplified example demonstrating the problem.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/facebookexperimental/Recoil/issues/914#issuecomment-833929099, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABUHIH7M5APKNOYGYFD3MODTMMNEZANCNFSM4YRIK2UA .

– Thanks, Nate!

There were some additional performance optimizations released with 0.2, I wonder if those may have helped this issue?

Interesting insight! (cc @davidmccabe)