Skip to content

feat: improve recursive diff performance#56

Merged
AsyncBanana merged 1 commit intoAsyncBanana:masterfrom
cn-stephen:recursive-perf
Apr 28, 2026
Merged

feat: improve recursive diff performance#56
AsyncBanana merged 1 commit intoAsyncBanana:masterfrom
cn-stephen:recursive-perf

Conversation

@cn-stephen
Copy link
Copy Markdown
Contributor

@cn-stephen cn-stephen commented Apr 23, 2026

Benchmark Mode Master recursive-perf Δ
PandaCSS Config no cycles 12.06 µs 10.62 µs −11.9%
PandaCSS Config cycles 17.48 µs 12.88 µs −26.3%
Scalar/OpenAPI Doc no cycles 7.44 µs 6.76 µs −9.1%
Scalar/OpenAPI Doc cycles 10.80 µs 8.14 µs −24.6%
Vanilla Extract Theme no cycles 6.99 µs 6.43 µs −8.0%
Vanilla Extract Theme cycles 9.07 µs 7.44 µs −18.0%
Large Object (300 props) no cycles 14.01 µs 13.62 µs −2.8%
Large Object (300 props) cycles 13.84 µs 13.76 µs −0.6%
Large Diff (300 props) no cycles 9.74 µs 9.42 µs −3.3%
Large Diff (300 props) cycles 9.62 µs 9.48 µs −1.5%
Deeply Nested Object no cycles 144.1 µs 120.1 µs −16.7%
Deeply Nested Object cycles 180.9 µs 131.4 µs −27.3%
Small Object no cycles 65.81 ns 67.78 ns +3.0%
Small Object cycles 65.37 ns 66.95 ns +2.4%

@cn-stephen cn-stephen marked this pull request as ready for review April 23, 2026 19:03
@AsyncBanana
Copy link
Copy Markdown
Owner

Have you tried mutating an array instead of a set? I haven't tested it, but it might be faster because it will avoid all of the hash table's overhead and shouldn't require any searches for insertion/deletion (you should just be able to insert/delete from the end).

@cn-stephen
Copy link
Copy Markdown
Contributor Author

YEP! very clever. Array wins!

Benchmark Mode Master recursive-perf Δ (array) Δ (Set)
PandaCSS Config no cycles 12.06 µs 10.51 µs −12.9% −11.9%
PandaCSS Config cycles 17.48 µs 10.66 µs −39.0% −26.3%
Scalar/OpenAPI Doc no cycles 7.44 µs 6.80 µs −8.6% −9.1%
Scalar/OpenAPI Doc cycles 10.80 µs 6.93 µs −35.8% −24.6%
Vanilla Extract Theme no cycles 6.99 µs 6.43 µs −8.0% −8.0%
Vanilla Extract Theme cycles 9.07 µs 6.49 µs −28.4% −18.0%
Large Object (300 props) no cycles 14.01 µs 13.61 µs −2.9% −2.8%
Large Object (300 props) cycles 13.84 µs 13.69 µs −1.1% −0.6%
Large Diff (300 props) no cycles 9.74 µs 9.61 µs −1.3% −3.3%
Large Diff (300 props) cycles 9.62 µs 9.49 µs −1.4% −1.5%
Deeply Nested Object no cycles 144.1 µs 126.2 µs −12.4% −16.7%
Deeply Nested Object cycles 180.9 µs 130.5 µs −27.9% −27.3%
Small Object no cycles 65.81 ns 64.33 ns −2.2% +3.0%
Small Object cycles 65.37 ns 62.75 ns −4.0% +2.4%

@cn-stephen
Copy link
Copy Markdown
Contributor Author

I think we can remove cyclesFix option altogether

@AsyncBanana
Copy link
Copy Markdown
Owner

Those results are great! I am going to run a few more tests, but I think you might be right. The overhead is so negligible at this point that we might as well have it on by default.

@AsyncBanana
Copy link
Copy Markdown
Owner

I haven't been able to test everything yet, but I am going to merge this anyway. Thanks!

@AsyncBanana AsyncBanana merged commit a28355b into AsyncBanana:master Apr 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants