Skip to content

Commit a6539ec

Browse files
BridgeARaddaleax
authored andcommitted
assert: optimize code path for deepEqual Maps
PR-URL: #14501 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>
1 parent 1168410 commit a6539ec

File tree

1 file changed

+18
-27
lines changed

1 file changed

+18
-27
lines changed

lib/assert.js

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,6 @@ function setEquiv(a, b, strict, memo) {
349349
// This is a lazily initiated Set of entries which have to be compared
350350
// pairwise.
351351
var set = null;
352-
// When the sets contain only value types (eg, lots of numbers), and we're in
353-
// strict mode or if all entries strictly match, we don't need to match the
354-
// entries in a pairwise way. In that case this initialization is done lazily
355-
// to avoid the allocation & bookkeeping cost.
356352
for (const val of a) {
357353
// Note: Checking for the objects first improves the performance for object
358354
// heavy sets but it is a minor slow down for primitives. As they are fast
@@ -373,7 +369,7 @@ function setEquiv(a, b, strict, memo) {
373369

374370
if (set !== null) {
375371
for (const val of b) {
376-
// In non-strict-mode we have to check if a primitive value is already
372+
// We have to check if a primitive value is already
377373
// matching and only if it's not, go hunting for it.
378374
if (typeof val === 'object' && val !== null) {
379375
if (!setHasEqualElement(set, val, strict, memo))
@@ -449,10 +445,13 @@ function mapHasLoosePrim(a, b, key1, memo, item1, item2) {
449445
return false;
450446

451447
for (const val of setA) {
452-
if (!setHasEqualElement(setB, val, false, memo))
448+
if (typeof val === 'object' && val !== null) {
449+
if (!setHasEqualElement(setB, val, false, memo))
450+
return false;
451+
} else if (!setB.has(val) && !setHasLoosePrim(setA, setB, val)) {
453452
return false;
453+
}
454454
}
455-
456455
return true;
457456
}
458457

@@ -472,34 +471,26 @@ function mapHasEqualEntry(set, map, key1, item1, strict, memo) {
472471
}
473472

474473
function mapEquiv(a, b, strict, memo) {
475-
// Caveat: In non-strict mode, this implementation does not handle cases
476-
// where maps contain two equivalent-but-not-reference-equal keys.
477474
if (a.size !== b.size)
478475
return false;
479476

480477
var set = null;
481478

482479
for (const [key, item1] of a) {
483-
// By directly retrieving the value we prevent another b.has(key) check in
484-
// almost all possible cases.
485-
const item2 = b.get(key);
486-
if (item2 === undefined) {
487-
// Just like setEquiv above but in addition we have to make sure the
488-
// values are also equal.
489-
if (typeof key === 'object' && key !== null) {
490-
if (set === null) {
491-
set = new Set();
492-
}
493-
set.add(key);
494-
// Note: we do not have to pass memo in this case as at least one item
495-
// is undefined.
496-
} else if ((!innerDeepEqual(item1, item2, strict) || !b.has(key)) &&
497-
(strict || !mapHasLoosePrim(a, b, key, memo, item1))) {
480+
if (typeof key === 'object' && key !== null) {
481+
if (set === null) {
482+
set = new Set();
483+
}
484+
set.add(key);
485+
} else {
486+
// By directly retrieving the value we prevent another b.has(key) check in
487+
// almost all possible cases.
488+
const item2 = b.get(key);
489+
if ((item2 === undefined && !b.has(key) ||
490+
!innerDeepEqual(item1, item2, strict, memo)) &&
491+
(strict || !mapHasLoosePrim(a, b, key, memo, item1, item2))) {
498492
return false;
499493
}
500-
} else if (!innerDeepEqual(item1, item2, strict, memo) &&
501-
(strict || !mapHasLoosePrim(a, b, key, memo, item1, item2))) {
502-
return false;
503494
}
504495
}
505496

0 commit comments

Comments
 (0)