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
- fix selectorGetter performance issue (#1515) Summary: The current algorithm for updating selector dependencies in the data flow graph is expensive. Currently we update the graph every time a new dep... — committed to drarmstr/Recoil by thomaszdxsn 2 years ago
- fix selectorGetter performance issue (#1515) Summary: The current algorithm for updating selector dependencies in the data flow graph is expensive. Currently we update the graph every time a new dep... — committed to facebookexperimental/Recoil by thomaszdxsn 2 years ago
- fix selectorGetter performance issue (#1515) Summary: The current algorithm for updating selector dependencies in the data flow graph is expensive. Currently we update the graph every time a new dep... — committed to AlexGuz23/Recoil by jackwolfskin0302 2 years ago
- fix selectorGetter performance issue (#1515) Summary: The current algorithm for updating selector dependencies in the data flow graph is expensive. Currently we update the graph every time a new dep... — committed to snipershooter0701/Recoil by thomaszdxsn 2 years ago
After some digging I found that the
mergeDependencyMapIntoGraphfunction will be called every time a get operation in the selector is called, and the size ofdeps, which will be iterated, grows as the number ofgetfunction calls, hence as we call moregetin 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? @drarmstrI’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:
– 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)