Potential bug discovered during benchmark stress tests #949
-
Bug DescriptionI created a comparison of the most popular TS reactivity libs, including Valtio. During my deep-dive, I wanted to benchmark all of them and created a fork of @milomg's excellent js-reactivity-benchmark, which includes dozens of benchmarks and stress tests. The problem is that Valtio fails to complete some of the dynamic benchmark tests in the suite. I've been unable to track down the source of the issue, whether it may be due to a rare bug in Valtio or possibly due to a bug in the Valtio adapter used by the benchmark. Note that this was a bit of an awkward adapter to write given that Valtio doesn't automatically track dependencies like many other reactive libs (#149). How to reproduce the issue:
The valtio benchmark tests work fine for the first test case but then hangs on the second (slightly larger) test case. Note that these test cases are creating a rectangular grid of shallow signals, where each layer of the grid contains CPU remains at 100% for the hung test with RAM usage flat around 75MB which seems reasonable. I've paired down this branch as much as possible to try and make it easier to debug. Note that in the full benchmark branch, all of the other reactivity libs are able to pass these benchmark tests, except for MobX which runs into a similar issue (mobxjs/mobx#3926). Versions
Reproduction Link |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 10 replies
-
Tried it, but hard to tell. |
Beta Was this translation helpful? Give feedback.
-
proper
|
Beta Was this translation helpful? Give feedback.
-
computed cache
I'm actually interested in it. Computeds are one of most requested features from the start. We had So, in Valtio, our recommended pattern for computeds is now using object getters. This it not actually a computed. But, it covers lots of Valtio use cases with React. It's because the caching works with snapshot. So, would you be able to try something like this? const p = proxy({
count: 0,
get double() {
// some heavy computation here
return this.count * 2;
},
});
const s1 = snapshot(p);
const s2 = snapshot(p);
s1 === s2 // is true as snapshots are cached Is it possible to use this behavior in your benchmark? |
Beta Was this translation helpful? Give feedback.
-
possible core extension
That is very true.
Having that said, I'm actually open to suggestions.
Can you help me understand the goal here? Is it like tracking based on #931 exposes some internals, and we can experiment various things outside the core. |
Beta Was this translation helpful? Give feedback.
Tried it, but hard to tell.
The adapter seems tricky, especially with computed. I'm not sure how watchGet hack works either.
I think it may require more work to add a reactive layer on top of valtio.
Can you investigate how 100% CPU is caused by?
sync: true
is causing an infinite loop?