From 71261b671062cad9f46c0fe2b219cf465a324cad Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Sat, 21 Dec 2024 13:09:10 +0000 Subject: [PATCH] Improve index join perf by picking shorter side to loop over --- packages/d2ts/src/version-index.ts | 39 +++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/d2ts/src/version-index.ts b/packages/d2ts/src/version-index.ts index 5c134bb..3e9bbe0 100644 --- a/packages/d2ts/src/version-index.ts +++ b/packages/d2ts/src/version-index.ts @@ -104,18 +104,45 @@ export class Index implements IndexType { () => [], ) - for (const [key, versions] of this.#inner) { - if (!other.#inner.has(key)) continue + // We want to iterate over the smaller of the two indexes to reduce the + // number of operations we need to do. + let inner1 + let inner2 + let direction: 'left' | 'right' + if (this.#inner.size <= other.#inner.size) { + inner1 = this.#inner + inner2 = other.#inner + direction = 'left' + } else { + inner1 = other.#inner + inner2 = this.#inner + direction = 'right' + } + + for (const [key, versions1] of inner1) { + if (!inner2.has(key)) continue - const otherVersions = other.#inner.get(key) + const versions2 = inner2.get(key) - for (const [version1, data1] of versions) { - for (const [version2, data2] of otherVersions) { + for (const [version1, data1] of versions1) { + for (const [version2, data2] of versions2) { for (const [val1, mul1] of data1) { for (const [val2, mul2] of data2) { const resultVersion = version1.join(version2) collections.update(resultVersion, (existing) => { - existing.push([key, [val1, val2], mul1 * mul2]) + if (direction === 'left') { + existing.push([key, [val1, val2], mul1 * mul2] as [ + K, + [V, V2], + number, + ]) + } else { + existing.push([key, [val2, val1], mul1 * mul2] as [ + K, + [V, V2], + number, + ]) + } return existing }) }