From 2d65adbb709e2cb337d8efbb19d69b5f610de905 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 11 May 2021 11:09:40 -0400 Subject: [PATCH 1/4] Add Node.js 16 to the test suite. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a9ec9a78..d08c14f1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node_version: ['10', '12', '14', '15'] + node_version: ['10', '12', '14', '15', '16'] os: [ubuntu-latest] steps: From 15397cb5a06c31539d0c4213cfb71208fd64572b Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 11 May 2021 11:06:25 -0400 Subject: [PATCH 2/4] Add basic performance tests to @wry/trie package. --- packages/trie/src/tests.ts | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/packages/trie/src/tests.ts b/packages/trie/src/tests.ts index 1c6397e1..ffac144a 100644 --- a/packages/trie/src/tests.ts +++ b/packages/trie/src/tests.ts @@ -87,4 +87,72 @@ describe("Trie", function () { // Verify that all Data objects are distinct. assert.strictEqual(new Set(datas).size, datas.length); }); + + describe("performance", () => { + const objectKeys: object[][] = []; + for (let k = 0; k < 2e4; ++k) { + const key: object[] = []; + for (let i = 0; i < 100; ++i) { + key.push({}); + } + objectKeys.push(key); + } + + const numberKeys: number[][] = []; + for (let k = 0; k < 2e4; ++k) { + const key: number[] = []; + for (let i = 0; i < 100; ++i) { + key.push(i * k); + } + numberKeys.push(key); + } + + it("lots of fresh object references added weakly", function () { + this.timeout(20000); + const trie = new Trie(true); + objectKeys.forEach(key => { + trie.lookupArray(key); + }); + }); + + it("lots of fresh object references added strongly", function () { + this.timeout(20000); + const trie = new Trie(false); + objectKeys.forEach(key => { + trie.lookupArray(key); + }); + }); + + it("lots of numeric key arrays added weakly", function () { + this.timeout(20000); + const trie = new Trie(true); + numberKeys.forEach(key => { + trie.lookupArray(key); + }); + }); + + it("lots of numeric key arrays added strongly", function () { + this.timeout(20000); + const trie = new Trie(false); + numberKeys.forEach(key => { + trie.lookupArray(key); + }); + }); + + it("looking up the same key lots of times, weakly", function () { + this.timeout(20000); + const trie = new Trie(true); + objectKeys.forEach(() => { + trie.lookupArray(objectKeys[0]); + }); + }); + + it("looking up the same key lots of times, strongly", function () { + this.timeout(20000); + const trie = new Trie(false); + objectKeys.forEach(() => { + trie.lookupArray(objectKeys[0]); + }); + }); + }); }); From 25c2cc87c600dc3d25971c675c56e472c225a914 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 11 May 2021 11:26:53 -0400 Subject: [PATCH 3/4] Use for loop instead of Array.prototype.forEach in lookupArray. --- packages/trie/src/trie.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/trie/src/trie.ts b/packages/trie/src/trie.ts index c208e3ce..124af1dc 100644 --- a/packages/trie/src/trie.ts +++ b/packages/trie/src/trie.ts @@ -6,8 +6,7 @@ // null-prototype Object. const defaultMakeData = () => Object.create(null); -// Useful for processing arguments objects as well as arrays. -const { forEach, slice } = Array.prototype; +const { slice } = Array.prototype; export class Trie { // Since a `WeakMap` cannot hold primitive values as keys, we need a @@ -27,8 +26,11 @@ export class Trie { } public lookupArray(array: T): Data { + const { length } = array; let node: Trie = this; - forEach.call(array, key => node = node.getChildTrie(key)); + for (let i = 0; i < length; ++i) { + node = node.getChildTrie(array[i]); + } return node.data || (node.data = this.makeData(slice.call(array))); } From c6756cb7a690b4efa1e579794b845294b5c8eab5 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 11 May 2021 11:39:09 -0400 Subject: [PATCH 4/4] Skip bizarrely slow performance test in Node.js 10. --- packages/trie/src/tests.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/trie/src/tests.ts b/packages/trie/src/tests.ts index ffac144a..c765c6f7 100644 --- a/packages/trie/src/tests.ts +++ b/packages/trie/src/tests.ts @@ -107,7 +107,10 @@ describe("Trie", function () { numberKeys.push(key); } - it("lots of fresh object references added weakly", function () { + const nodeMajorVersion = parseInt(process.versions.node.split('.')[0], 10); + + (nodeMajorVersion > 10 ? it : it.skip) + ("lots of fresh object references added weakly", function () { this.timeout(20000); const trie = new Trie(true); objectKeys.forEach(key => {