From 3fda942114e0780d61cdb29cb26e45010d98abb8 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Wed, 26 Jul 2017 09:58:26 -0300 Subject: [PATCH 1/2] assert: optimize code path for deepEqual Maps --- lib/assert.js | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index f7a3350db10f1f..bdbb3ce4482f08 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -453,10 +453,13 @@ function mapHasLoosePrim(a, b, key1, memo, item1, item2) { return false; for (const val of setA) { - if (!setHasEqualElement(setB, val, false, memo)) + if (typeof val === 'object' && val !== null) { + if (!setHasEqualElement(setB, val, false, memo)) + return false; + } else if (!setB.has(val) && !setHasLoosePrim(setA, setB, val)) { return false; + } } - return true; } @@ -484,26 +487,20 @@ function mapEquiv(a, b, strict, memo) { var set = null; for (const [key, item1] of a) { - // By directly retrieving the value we prevent another b.has(key) check in - // almost all possible cases. - const item2 = b.get(key); - if (item2 === undefined) { - // Just like setEquiv above but in addition we have to make sure the - // values are also equal. - if (typeof key === 'object' && key !== null) { - if (set === null) { - set = new Set(); - } - set.add(key); - // Note: we do not have to pass memo in this case as at least one item - // is undefined. - } else if ((!innerDeepEqual(item1, item2, strict) || !b.has(key)) && - (strict || !mapHasLoosePrim(a, b, key, memo, item1))) { + if (typeof key === 'object' && key !== null) { + if (set === null) { + set = new Set(); + } + set.add(key); + } else { + // By directly retrieving the value we prevent another b.has(key) check in + // almost all possible cases. + const item2 = b.get(key); + if ((item2 === undefined && !b.has(key) || + !innerDeepEqual(item1, item2, strict, memo)) && + (strict || !mapHasLoosePrim(a, b, key, memo, item1, item2))) { return false; } - } else if (!innerDeepEqual(item1, item2, strict, memo) && - (strict || !mapHasLoosePrim(a, b, key, memo, item1, item2))) { - return false; } } From b5156242501531028f183d999197b9b709fcfa36 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Wed, 26 Jul 2017 10:02:23 -0300 Subject: [PATCH 2/2] assert: remove and improve a few comments --- lib/assert.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index bdbb3ce4482f08..82638362e84a5a 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -353,10 +353,6 @@ function setEquiv(a, b, strict, memo) { // This is a lazily initiated Set of entries which have to be compared // pairwise. var set = null; - // When the sets contain only value types (eg, lots of numbers), and we're in - // strict mode or if all entries strictly match, we don't need to match the - // entries in a pairwise way. In that case this initialization is done lazily - // to avoid the allocation & bookkeeping cost. for (const val of a) { // Note: Checking for the objects first improves the performance for object // heavy sets but it is a minor slow down for primitives. As they are fast @@ -377,7 +373,7 @@ function setEquiv(a, b, strict, memo) { if (set !== null) { for (const val of b) { - // In non-strict-mode we have to check if a primitive value is already + // We have to check if a primitive value is already // matching and only if it's not, go hunting for it. if (typeof val === 'object' && val !== null) { if (!setHasEqualElement(set, val, strict, memo)) @@ -479,8 +475,6 @@ function mapHasEqualEntry(set, map, key1, item1, strict, memo) { } function mapEquiv(a, b, strict, memo) { - // Caveat: In non-strict mode, this implementation does not handle cases - // where maps contain two equivalent-but-not-reference-equal keys. if (a.size !== b.size) return false;