-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
assert: Add support for Map and Set in deepEqual #12142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
561561a
f051840
1d6cda6
800ae46
031f6f3
d6baaee
8fb6ebf
acef701
ee131e8
7bc29b0
6bdfcaf
fc5196a
7f9d4d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -300,13 +300,15 @@ function setEquiv(a, b, strict, actualVisitedObjects) { | |
|
|
||
| outer: for (const val1 of a) { | ||
| if (!b.has(val1)) { | ||
| // The value doesn't exist in the second set by reference, so we'll go | ||
| // hunting for something thats deep-equal to it. Note that this is O(n^2) | ||
| // complexity, and will get slower if large, very similar sets / maps are | ||
| // nested inside. Unfortunately there's no real way around this. | ||
| for (const val2 of b) { | ||
| if (_deepEqual(val1, val2, strict, actualVisitedObjects)) { | ||
| continue outer; | ||
| if (!strict || typeof val1 === 'object') { | ||
| // The value doesn't exist in the second set by reference, so we'll go | ||
| // hunting for something thats deep-equal to it. Note that this is | ||
| // O(n^2) complexity, and will get slower if large, very similar sets / | ||
| // maps are nested inside. Unfortunately there's no real way around | ||
| // this. | ||
| for (const val2 of b) { | ||
|
||
| if (_deepEqual(val1, val2, strict, actualVisitedObjects)) | ||
| continue outer; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -333,24 +335,27 @@ function mapEquiv(a, b, strict, actualVisitedObjects) { | |
| // Map([[{}, 'a'], [{}, 'b']]) vs Map([[{}, 'b'], [{}, 'a']]) | ||
| // ... we need to consider *all* matching keys, not just the first we find. | ||
|
|
||
| // This check is not strictly necessary, but its here to improve | ||
| // performance of the common case when reference-equal keys exist (which | ||
| // includes all primitive-valued keys). | ||
| // This check is not strictly necessary if we run the loop below, but it | ||
| // improves performance of the common case when reference-equal keys exist | ||
| // (which includes all primitive-valued keys). | ||
| if (b.has(key1)) { | ||
| if (_deepEqual(item1, b.get(key1), strict, actualVisitedObjects)) | ||
| continue outer; | ||
| } | ||
|
|
||
| // Hunt for keys which are deep-equal to key1 in b. Just like setEquiv | ||
| // above, this hunt makes this function O(n^2). | ||
| for (const [key2, item2] of b) { | ||
| // Just for performance. We already checked these keys above. | ||
| if (key2 === key1) | ||
| continue; | ||
|
|
||
| if (_deepEqual(key1, key2, strict, actualVisitedObjects) && | ||
| _deepEqual(item1, item2, strict, actualVisitedObjects)) { | ||
| continue outer; | ||
| // above, this hunt makes this function O(n^2) when using objects and lists | ||
| // as keys | ||
| if (!strict || typeof key1 === 'object') { | ||
| for (const [key2, item2] of b) { | ||
| // Just for performance. We already checked these keys above. | ||
| if (key2 === key1) | ||
| continue; | ||
|
|
||
| if (_deepEqual(key1, key2, strict, actualVisitedObjects) && | ||
| _deepEqual(item1, item2, strict, actualVisitedObjects)) { | ||
| continue outer; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(!strict || (typeof val1 === 'object' && val1 !== null) || typeof val1 === 'function')?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to search for functions because the only way deepEqual will consider functions equivalent is through reference equality. The null check makes some sense, although I think it'll make a very small difference in practice because putting null in a set and using null as a key are rare. (In my code, null popping up in either of those places is usually an indication of a bug)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a minor point, but do you think its still worth putting in the null check? I'm indifferent either way, but happy to add it if you think the marginal speed improvement is worth the marginal extra complexity of that check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@josephg Yes, I’d say it’s worth it… there might be cases where the difference is not so marginal, and I think it’s okay for Node core to sacrifice a tiny bit of readability for a small performance gain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done