diff options
author | Ruben Bridgewater <ruben@bridgewater.de> | 2017-07-26 08:58:26 -0400 |
---|---|---|
committer | Refael Ackermann <refack@gmail.com> | 2017-08-13 13:58:11 -0400 |
commit | 9222fe64ad4f624a50551ef5289cdb0bc333a4bc (patch) | |
tree | 845a45d0efc37169051f5a8e0b252a6ac1e8c871 /lib/assert.js | |
parent | 95bbb6817532a2cdf1991f452ebbc5a5b5d5a112 (diff) | |
download | android-node-v8-9222fe64ad4f624a50551ef5289cdb0bc333a4bc.tar.gz android-node-v8-9222fe64ad4f624a50551ef5289cdb0bc333a4bc.tar.bz2 android-node-v8-9222fe64ad4f624a50551ef5289cdb0bc333a4bc.zip |
assert: optimize code path for deepEqual Maps
PR-URL: https://github.com/nodejs/node/pull/14501
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Diffstat (limited to 'lib/assert.js')
-rw-r--r-- | lib/assert.js | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/lib/assert.js b/lib/assert.js index 1350f0abbb..b9c2c94ec3 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -360,10 +360,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 @@ -384,7 +380,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)) @@ -460,10 +456,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; } @@ -483,34 +482,26 @@ 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; 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; } } |