You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Description
Improve performance of this function that gets called a lot for
structural sharing. Main improvements are
- avoid creating object when possible
(`Object.keys().concat(Object.getOwnPropertySymbols())` creates 3
arrays, when we only want 1)
- instantiating array to the correct size avoids a lot of memory
management under the hood (prefer `new Array(size)` over `[]`)
- avoid reading the same value many times on an object, store is as a
const
More minor changes (not 100% sure I can measure it, but I think so):
- using `keys.includes(k)` is slower than
`Object.hasOwnProperty.call(obj, k)` or `obj.hasOwnProperty(k)`
## benchmark
TL;DR: consistently 1.3x faster implementation
```ts
describe('replaceEqualDeep', () => {
bench('old implementation', () => {
replaceEqualDeepOld({ a: 1, b: [2, 3] }, { a: 1, b: [2, 3] })
replaceEqualDeepOld({ a: 1, b: [2, 3] }, { a: 2, b: [2] })
})
bench('new implementation', () => {
replaceEqualDeep({ a: 1, b: [2, 3] }, { a: 1, b: [2, 3] })
replaceEqualDeep({ a: 1, b: [2, 3] }, { a: 2, b: [2] })
})
})
```
```sh
✓ @tanstack/router-core tests/utils.bench.ts > replaceEqualDeep 1540ms
name hz min max mean p75 p99 p995 p999 rme samples
· old implementation 1,040,201.62 0.0008 0.7638 0.0010 0.0010 0.0013 0.0016 0.0022 ±0.33% 520101
· new implementation 1,347,988.70 0.0006 2.4037 0.0007 0.0007 0.0010 0.0010 0.0013 ±0.95% 673995 fastest
BENCH Summary
@tanstack/router-core new implementation - tests/utils.bench.ts > replaceEqualDeep
1.30x faster than old implementation
```
---
The `replaceEqualDeep` implementation before this PR handles Symbol
keys, and non-enumerable keys (see
#4237), but **not** keys that are
both a Symbol and non-enumerable.
This PR fixes this issue. But if we also fix it in the previous
implementation before comparing performance we get a bigger perf diff
```sh
✓ @tanstack/router-core tests/utils.bench.ts > replaceEqualDeep 1471ms
name hz min max mean p75 p99 p995 p999 rme samples
· old implementation 713,964.88 0.0012 0.7880 0.0014 0.0014 0.0019 0.0023 0.0050 ±0.35% 356983
· new implementation 1,319,003.07 0.0006 5.0000 0.0008 0.0007 0.0010 0.0016 0.0050 ±1.96% 659502 fastest
BENCH Summary
@tanstack/router-core new implementation - tests/utils.bench.ts > replaceEqualDeep
1.85x faster than old implementation
```
---
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Change detection now includes symbol-keyed properties, treats
undefined/missing entries consistently, and avoids processing objects
with non-enumerable own properties to prevent incorrect updates.
* No public API changes.
* **Performance**
* Equality/merge logic reuses unchanged values more reliably and
improves array update handling by allocating appropriately, reducing
unnecessary work.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
0 commit comments