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
mergeDependencyMapIntoGraph
function 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 ofget
function calls, hence as we call moreget
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? @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)