diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1593cfd..d72fd98 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
-## [v1.45.0](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
+## [v1.45.1](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes
diff --git a/COMMANDS.md b/COMMANDS.md
index b1aedba..9a745a4 100644
--- a/COMMANDS.md
+++ b/COMMANDS.md
@@ -5,12 +5,17 @@ Overview of the commands to test, run and build this project as well as those th
## Most important commands for development
- `npm install` Installs all dependencies and creates the folder `node_modules`, that is needed for all following commands.
+- `npm run lint` Lint src/ and test/ codebase (using ESLint)
+- `npm run format` Pretty src/ and test/ codebase (using Prettier)
+- `npm run inspect` Check src/ and test/ codebase (using TSC and ESLint)
- `npm run changelog` Update CHANGELOG.md
- `npm login` + `npm publish` To publish a new release. Be sure to run npm run package first.
## Commands to test, run and build the project
-- `npm test` Run all unit tests (using Jest) with reporting coverage
+- `npm test` or `npm run test:unit` Run all unit tests (using Jest) with reporting coverage
+- `npm test:perf` Run all performance tests (using Benchmark.js) with reporting results
+- `npm run test:perf -- priority-queue.test` Run specific performance test
[//]: # (- `npm run coverage-badge` Updates code coverage badge inside `README.md`)
- `npm run build:docs` Generates JSDoc Documentation in folder "docs"
diff --git a/README.md b/README.md
index 1993ffe..bac0803 100644
--- a/README.md
+++ b/README.md
@@ -734,50 +734,53 @@ optimal approach to data structure design.
[//]: # (No deletion!!! Start of Replace Section)
+
comparation
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
SRC 10,000 add | 0.59 | 1701.78 | 3.28e-5 |
CJS 10,000 add | 0.61 | 1648.70 | 6.98e-5 |
MJS 10,000 add | 0.59 | 1691.86 | 2.44e-5 |
SRC PQ 10,000 add & pop | 4.97 | 201.19 | 1.37e-4 |
CJS PQ 10,000 add & pop | 4.93 | 202.70 | 5.60e-5 |
MJS PQ 10,000 add & pop | 4.98 | 200.74 | 4.39e-4 |
+
avl-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 33.34 | 29.99 | 0.00 |
10,000 add & delete randomly | 72.30 | 13.83 | 0.00 |
10,000 addMany | 49.50 | 20.20 | 0.00 |
10,000 get | 27.23 | 36.73 | 7.19e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 32.27 | 30.99 | 0.00 |
10,000 add & delete randomly | 73.67 | 13.57 | 0.00 |
10,000 addMany | 41.81 | 23.92 | 0.00 |
10,000 get | 29.21 | 34.24 | 0.00 |
binary-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 add randomly | 12.20 | 81.97 | 8.36e-5 |
1,000 add & delete randomly | 15.93 | 62.77 | 2.09e-4 |
1,000 addMany | 10.36 | 96.56 | 2.01e-4 |
1,000 get | 18.43 | 54.26 | 4.67e-4 |
1,000 dfs | 154.61 | 6.47 | 0.00 |
1,000 bfs | 57.73 | 17.32 | 0.01 |
1,000 morris | 258.47 | 3.87 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 add randomly | 13.82 | 72.38 | 0.00 |
1,000 add & delete randomly | 16.01 | 62.45 | 5.80e-4 |
1,000 addMany | 12.30 | 81.33 | 0.01 |
1,000 get | 19.75 | 50.63 | 0.01 |
1,000 dfs | 157.12 | 6.36 | 0.00 |
1,000 bfs | 56.72 | 17.63 | 4.27e-4 |
1,000 morris | 334.97 | 2.99 | 0.03 |
bst
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 29.44 | 33.96 | 3.99e-4 |
10,000 add & delete randomly | 72.35 | 13.82 | 0.00 |
10,000 addMany | 29.76 | 33.60 | 0.00 |
10,000 get | 28.53 | 35.05 | 5.76e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 28.30 | 35.34 | 0.00 |
10,000 add & delete randomly | 67.47 | 14.82 | 0.00 |
10,000 addMany | 29.25 | 34.18 | 0.00 |
10,000 get | 30.53 | 32.75 | 0.01 |
rb-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 90.42 | 11.06 | 0.01 |
100,000 add & delete randomly | 223.52 | 4.47 | 0.02 |
100,000 getNode | 38.67 | 25.86 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 96.67 | 10.34 | 0.01 |
100,000 add & delete randomly | 224.85 | 4.45 | 0.01 |
100,000 getNode | 40.83 | 24.49 | 2.73e-4 |
directed-graph
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 addVertex | 0.11 | 9499.56 | 5.09e-6 |
1,000 addEdge | 6.37 | 157.04 | 8.13e-4 |
1,000 getVertex | 0.05 | 2.15e+4 | 1.20e-6 |
1,000 getEdge | 22.44 | 44.56 | 0.00 |
tarjan | 213.53 | 4.68 | 0.01 |
tarjan all | 215.75 | 4.63 | 0.00 |
topologicalSort | 175.51 | 5.70 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 addVertex | 0.11 | 9364.63 | 1.25e-5 |
1,000 addEdge | 6.18 | 161.78 | 1.26e-4 |
1,000 getVertex | 0.05 | 2.12e+4 | 4.19e-6 |
1,000 getEdge | 25.98 | 38.50 | 0.01 |
tarjan | 240.23 | 4.16 | 0.02 |
tarjan all | 227.36 | 4.40 | 0.00 |
topologicalSort | 185.85 | 5.38 | 0.00 |
hash-map
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 set | 0.76 | 1308.63 | 1.65e-5 |
10,000 set & get | 1.03 | 966.59 | 2.21e-5 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 set | 1.00 | 1001.31 | 1.82e-5 |
10,000 set & get | 1.54 | 650.14 | 4.87e-5 |
heap
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add & pop | 4.65 | 214.92 | 1.18e-4 |
10,000 fib add & pop | 367.35 | 2.72 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add & pop | 6.97 | 143.49 | 5.27e-4 |
10,000 fib add & pop | 378.40 | 2.64 | 0.05 |
doubly-linked-list
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 unshift | 222.80 | 4.49 | 0.06 |
1,000,000 unshift & shift | 174.60 | 5.73 | 0.04 |
1,000,000 insertBefore | 309.21 | 3.23 | 0.07 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 unshift | 224.55 | 4.45 | 0.07 |
1,000,000 unshift & shift | 182.17 | 5.49 | 0.06 |
1,000,000 insertBefore | 342.63 | 2.92 | 0.08 |
singly-linked-list
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 push & pop | 214.75 | 4.66 | 0.01 |
10,000 insertBefore | 250.45 | 3.99 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 push & pop | 222.42 | 4.50 | 0.01 |
10,000 insertBefore | 248.39 | 4.03 | 0.00 |
max-priority-queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 refill & poll | 11.44 | 87.43 | 1.80e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 refill & poll | 11.83 | 84.55 | 1.45e-4 |
priority-queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add & pop | 12.41 | 80.57 | 1.56e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add & pop | 10.79 | 92.72 | 2.01e-4 |
deque
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 219.15 | 4.56 | 0.04 |
1,000,000 shift | 26.76 | 37.37 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 231.33 | 4.32 | 0.06 |
1,000,000 shift | 27.64 | 36.17 | 0.01 |
queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 45.17 | 22.14 | 0.01 |
1,000,000 push & shift | 80.41 | 12.44 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 46.16 | 21.66 | 0.01 |
1,000,000 push & shift | 82.18 | 12.17 | 0.00 |
stack
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 43.67 | 22.90 | 0.01 |
1,000,000 push & pop | 48.18 | 20.76 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 45.45 | 22.00 | 0.01 |
1,000,000 push & pop | 50.10 | 19.96 | 0.01 |
trie
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 push | 60.46 | 16.54 | 0.00 |
100,000 getWords | 83.13 | 12.03 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 push | 46.25 | 21.62 | 0.00 |
100,000 getWords | 65.17 | 15.34 | 0.00 |
[//]: # (No deletion!!! End of Replace Section)
\ No newline at end of file
diff --git a/package.json b/package.json
index 2c3bacf..d49f2b0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
- "version": "1.45.0",
+ "version": "1.45.2",
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
diff --git a/src/data-structures/heap/heap.ts b/src/data-structures/heap/heap.ts
index 5850ba7..0bc2df6 100644
--- a/src/data-structures/heap/heap.ts
+++ b/src/data-structures/heap/heap.ts
@@ -305,18 +305,28 @@ export class Heap {
* @param index - The index of the newly added element.
*/
protected bubbleUp(index: number): void {
- const element = this.nodes[index];
+ // const element = this.nodes[index];
+ // while (index > 0) {
+ // const parentIndex = (index - 1) >> 1;
+ // const parent = this.nodes[parentIndex];
+ // if (this.comparator(element, parent) < 0) {
+ // this.nodes[index] = parent;
+ // this.nodes[parentIndex] = element;
+ // index = parentIndex;
+ // } else {
+ // break;
+ // }
+ // }
+
+ const item = this.nodes[index];
while (index > 0) {
- const parentIndex = Math.floor((index - 1) / 2);
- const parent = this.nodes[parentIndex];
- if (this.comparator(element, parent) < 0) {
- this.nodes[index] = parent;
- this.nodes[parentIndex] = element;
- index = parentIndex;
- } else {
- break;
- }
+ const parent = (index - 1) >> 1;
+ const parentItem = this.nodes[parent];
+ if (this.comparator(parentItem, item) <= 0) break;
+ this.nodes[index] = parentItem;
+ index = parent;
}
+ this.nodes[index] = item;
}
/**
@@ -332,8 +342,8 @@ export class Heap {
* @param index - The index from which to start sinking.
*/
protected sinkDown(index: number): void {
- const leftChildIndex = 2 * index + 1;
- const rightChildIndex = 2 * index + 2;
+ const leftChildIndex = index << 1 | 1;
+ const rightChildIndex = leftChildIndex + 1;
const length = this.nodes.length;
let targetIndex = index;
@@ -774,3 +784,117 @@ export class FibonacciHeap {
}
}
}
+
+
+export class CHeap {
+
+ protected _length = 0;
+ private readonly _priorityQueue: T[] = [];
+ private readonly _cmp: (x: T, y: T) => number;
+
+ constructor(
+ cmp: (x: T, y: T) => number =
+ function (x: T, y: T) {
+ if (x > y) return -1;
+ if (x < y) return 1;
+ return 0;
+ },
+ copy = true
+ ) {
+
+ this._cmp = cmp;
+
+ }
+
+ clear() {
+ this._length = 0;
+ this._priorityQueue.length = 0;
+ }
+
+ push(item: T) {
+ this._priorityQueue.push(item);
+ this._pushUp(this._length);
+ this._length += 1;
+ }
+
+ pop() {
+ if (this._length === 0) return;
+ const value = this._priorityQueue[0];
+ const last = this._priorityQueue.pop()!;
+ this._length -= 1;
+ if (this._length) {
+ this._priorityQueue[0] = last;
+ this._pushDown(0, this._length >> 1);
+ }
+ return value;
+ }
+
+ top(): T | undefined {
+ return this._priorityQueue[0];
+ }
+
+ find(item: T) {
+ return this._priorityQueue.indexOf(item) >= 0;
+ }
+
+ remove(item: T) {
+ const index = this._priorityQueue.indexOf(item);
+ if (index < 0) return false;
+ if (index === 0) {
+ this.pop();
+ } else if (index === this._length - 1) {
+ this._priorityQueue.pop();
+ this._length -= 1;
+ } else {
+ this._priorityQueue.splice(index, 1, this._priorityQueue.pop()!);
+ this._length -= 1;
+ this._pushUp(index);
+ this._pushDown(index, this._length >> 1);
+ }
+ return true;
+ }
+
+ updateItem(item: T) {
+ const index = this._priorityQueue.indexOf(item);
+ if (index < 0) return false;
+ this._pushUp(index);
+ this._pushDown(index, this._length >> 1);
+ return true;
+ }
+
+ toArray() {
+ return [...this._priorityQueue];
+ }
+
+ private _pushUp(pos: number) {
+ const item = this._priorityQueue[pos];
+ while (pos > 0) {
+ const parent = (pos - 1) >> 1;
+ const parentItem = this._priorityQueue[parent];
+ if (this._cmp(parentItem, item) <= 0) break;
+ this._priorityQueue[pos] = parentItem;
+ pos = parent;
+ }
+ this._priorityQueue[pos] = item;
+ }
+
+ private _pushDown(pos: number, halfLength: number) {
+ const item = this._priorityQueue[pos];
+ while (pos < halfLength) {
+ let left = pos << 1 | 1;
+ const right = left + 1;
+ let minItem = this._priorityQueue[left];
+ if (
+ right < this._length &&
+ this._cmp(minItem, this._priorityQueue[right]) > 0
+ ) {
+ left = right;
+ minItem = this._priorityQueue[right];
+ }
+ if (this._cmp(minItem, item) >= 0) break;
+ this._priorityQueue[pos] = minItem;
+ pos = left;
+ }
+ this._priorityQueue[pos] = item;
+ }
+}
diff --git a/test/performance/data-structures/binary-tree/rb-tree.test.ts b/test/performance/data-structures/binary-tree/rb-tree.test.ts
index 40af7ed..ca0dfcc 100644
--- a/test/performance/data-structures/binary-tree/rb-tree.test.ts
+++ b/test/performance/data-structures/binary-tree/rb-tree.test.ts
@@ -8,7 +8,7 @@ const suite = new Benchmark.Suite();
const rbTree = new RedBlackTree();
const { HUNDRED_THOUSAND } = magnitude;
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
-const competitor = new OrderedMap();
+const cOrderedMap = new OrderedMap();
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
rbTree.clear();
@@ -18,9 +18,9 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
});
if (isCompetitor) {
- suite.add(`${HUNDRED_THOUSAND.toLocaleString()} competitor add`, () => {
+ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} CPT add`, () => {
for (let i = 0; i < arr.length; i++) {
- competitor.setElement(arr[i], arr[i]);
+ cOrderedMap.setElement(arr[i], arr[i]);
}
});
}
diff --git a/test/performance/data-structures/comparation.test.ts b/test/performance/data-structures/comparation.test.ts
new file mode 100644
index 0000000..ae7ff99
--- /dev/null
+++ b/test/performance/data-structures/comparation.test.ts
@@ -0,0 +1,142 @@
+import { PriorityQueue as MJSPriorityQueue } from '../../../dist/cjs';
+import { PriorityQueue as SRCPriorityQueue } from '../../../src';
+import { PriorityQueue as CJSPriorityQueue } from '../../../dist/mjs';
+import {
+ Deque as CDeque,
+ HashMap as CHashMap,
+ LinkList as CLinkedList,
+ OrderedMap,
+ PriorityQueue as CPriorityQueue,
+ Queue as CQueue,
+ Stack as CStack
+} from 'js-sdsl';
+
+import * as Benchmark from 'benchmark';
+import { getRandomIntArray, magnitude } from '../../utils';
+import { isCompetitor } from '../../config';
+
+const suite = new Benchmark.Suite();
+const { TEN_THOUSAND, HUNDRED_THOUSAND, LINEAR } = magnitude;
+const cOrderedMap = new OrderedMap();
+const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
+
+suite.add(`SRC ${TEN_THOUSAND.toLocaleString()} add`, () => {
+
+ const pq = new SRCPriorityQueue({ comparator: (a, b) => b - a });
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
+}).add(`CJS ${TEN_THOUSAND.toLocaleString()} add`, () => {
+
+ const pq = new CJSPriorityQueue({ comparator: (a, b) => b - a });
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
+}).add(`MJS ${TEN_THOUSAND.toLocaleString()} add`, () => {
+
+ const pq = new MJSPriorityQueue({ comparator: (a, b) => b - a });
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
+});
+
+if (isCompetitor) {
+ suite.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
+
+ const pq = new CPriorityQueue();
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
+ });
+}
+
+suite.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
+ const pq = new SRCPriorityQueue({ comparator: (a, b) => b - a });
+
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
+}).add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
+ const pq = new CJSPriorityQueue({ comparator: (a, b) => b - a });
+
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
+}).add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
+ const pq = new MJSPriorityQueue({ comparator: (a, b) => b - a });
+
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
+});
+
+
+if (isCompetitor) {
+ suite.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
+ const pq = new CPriorityQueue();
+
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
+ })
+ .add(`CPT OM ${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
+ for (let i = 0; i < arrHundredThousand.length; i++) {
+ cOrderedMap.setElement(arrHundredThousand[i], arrHundredThousand[i]);
+ }
+ })
+ .add(`CPT HM ${TEN_THOUSAND.toLocaleString()} set`, () => {
+ const hm = new CHashMap();
+
+ for (let i = 0; i < TEN_THOUSAND; i++) {
+ hm.setElement(i, i);
+ }
+ })
+ .add(`CPT HM ${TEN_THOUSAND.toLocaleString()} set & get`, () => {
+ const hm = new CHashMap();
+
+ for (let i = 0; i < TEN_THOUSAND; i++) {
+ hm.setElement(i, i);
+ }
+ for (let i = 0; i < TEN_THOUSAND; i++) {
+ hm.getElementByKey(i);
+ }
+ })
+ .add(`CPT LL ${LINEAR.toLocaleString()} unshift`, () => {
+ const list = new CLinkedList();
+
+ for (let i = 0; i < LINEAR; i++) {
+ list.pushFront(i);
+ }
+ })
+ .add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
+ const pq = new CPriorityQueue();
+
+ for (let i = 0; i < TEN_THOUSAND; i++) {
+ pq.push(i);
+ }
+
+ for (let i = 0; i < TEN_THOUSAND; i++) {
+ pq.pop();
+ }
+ })
+ .add(`CPT DQ ${LINEAR.toLocaleString()} push`, () => {
+ const deque = new CDeque();
+ for (let i = 0; i < LINEAR; i++) {
+ deque.pushBack(i);
+ }
+ })
+ .add(`CPT Q ${LINEAR.toLocaleString()} push`, () => {
+ const queue = new CQueue();
+
+ for (let i = 0; i < LINEAR; i++) {
+ queue.push(i);
+ }
+ })
+ .add(`CPT ST ${LINEAR.toLocaleString()} push`, () => {
+ const queue = new CStack();
+
+ for (let i = 0; i < LINEAR; i++) {
+ queue.push(i);
+ }
+ })
+ .add(`CPT ST ${LINEAR.toLocaleString()} push & pop`, () => {
+ const queue = new CStack();
+
+ for (let i = 0; i < LINEAR; i++) {
+ queue.push(i);
+ }
+ for (let i = 0; i < LINEAR; i++) {
+ queue.pop();
+ }
+ });
+}
+
+export { suite };
diff --git a/test/performance/data-structures/hash/hash-map.test.ts b/test/performance/data-structures/hash/hash-map.test.ts
index f8adfde..b98890f 100644
--- a/test/performance/data-structures/hash/hash-map.test.ts
+++ b/test/performance/data-structures/hash/hash-map.test.ts
@@ -15,7 +15,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} set`, () => {
}
});
if (isCompetitor) {
- suite.add(`${TEN_THOUSAND.toLocaleString()} competitor set`, () => {
+ suite.add(`${TEN_THOUSAND.toLocaleString()} CPT set`, () => {
const hm = new CHashMap();
for (let i = 0; i < TEN_THOUSAND; i++) {
@@ -34,7 +34,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} set & get`, () => {
}
});
if (isCompetitor) {
- suite.add(`${TEN_THOUSAND.toLocaleString()} competitor set & get`, () => {
+ suite.add(`${TEN_THOUSAND.toLocaleString()} CPT set & get`, () => {
const hm = new CHashMap();
for (let i = 0; i < TEN_THOUSAND; i++) {
diff --git a/test/performance/data-structures/linked-list/doubly-linked-list.test.ts b/test/performance/data-structures/linked-list/doubly-linked-list.test.ts
index 2289343..b52fc6d 100644
--- a/test/performance/data-structures/linked-list/doubly-linked-list.test.ts
+++ b/test/performance/data-structures/linked-list/doubly-linked-list.test.ts
@@ -15,7 +15,7 @@ suite.add(`${LINEAR.toLocaleString()} unshift`, () => {
}
});
if (isCompetitor) {
- suite.add(`${LINEAR.toLocaleString()} competitor unshift`, () => {
+ suite.add(`${LINEAR.toLocaleString()} CPT unshift`, () => {
const list = new CLinkedList();
for (let i = 0; i < LINEAR; i++) {
diff --git a/test/performance/data-structures/priority-queue/priority-queue.test.ts b/test/performance/data-structures/priority-queue/priority-queue.test.ts
index cd54e4b..84c58b5 100644
--- a/test/performance/data-structures/priority-queue/priority-queue.test.ts
+++ b/test/performance/data-structures/priority-queue/priority-queue.test.ts
@@ -19,7 +19,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
}
});
if (isCompetitor) {
- suite.add(`${TEN_THOUSAND.toLocaleString()} competitor add & pop`, () => {
+ suite.add(`${TEN_THOUSAND.toLocaleString()} CPT add & pop`, () => {
const pq = new CPriorityQueue();
for (let i = 0; i < TEN_THOUSAND; i++) {
diff --git a/test/performance/data-structures/queue/deque.test.ts b/test/performance/data-structures/queue/deque.test.ts
index 526174a..dddad4e 100644
--- a/test/performance/data-structures/queue/deque.test.ts
+++ b/test/performance/data-structures/queue/deque.test.ts
@@ -14,7 +14,7 @@ suite.add(`${LINEAR.toLocaleString()} push`, () => {
}
});
if (isCompetitor) {
- suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
+ suite.add(`${LINEAR.toLocaleString()} CPT push`, () => {
const deque = new CDeque();
for (let i = 0; i < LINEAR; i++) {
deque.pushBack(i);
diff --git a/test/performance/data-structures/queue/queue.test.ts b/test/performance/data-structures/queue/queue.test.ts
index f2a2165..f1545b6 100644
--- a/test/performance/data-structures/queue/queue.test.ts
+++ b/test/performance/data-structures/queue/queue.test.ts
@@ -15,7 +15,7 @@ suite.add(`${LINEAR.toLocaleString()} push`, () => {
}
});
if (isCompetitor) {
- suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
+ suite.add(`${LINEAR.toLocaleString()} CPT push`, () => {
const queue = new CQueue();
for (let i = 0; i < LINEAR; i++) {
diff --git a/test/performance/data-structures/stack/stack.test.ts b/test/performance/data-structures/stack/stack.test.ts
index d1aac39..e4a2742 100644
--- a/test/performance/data-structures/stack/stack.test.ts
+++ b/test/performance/data-structures/stack/stack.test.ts
@@ -15,7 +15,7 @@ suite.add(`${LINEAR.toLocaleString()} push`, () => {
}
});
if (isCompetitor) {
- suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
+ suite.add(`${LINEAR.toLocaleString()} CPT push`, () => {
const queue = new CStack();
for (let i = 0; i < LINEAR; i++) {
@@ -34,7 +34,7 @@ suite.add(`${LINEAR.toLocaleString()} push & pop`, () => {
}
});
if (isCompetitor) {
- suite.add(`${LINEAR.toLocaleString()} competitor push & pop`, () => {
+ suite.add(`${LINEAR.toLocaleString()} CPT push & pop`, () => {
const queue = new CStack();
for (let i = 0; i < LINEAR; i++) {
diff --git a/test/performance/reportor.ts b/test/performance/reportor.ts
index 1013406..447fa87 100644
--- a/test/performance/reportor.ts
+++ b/test/performance/reportor.ts
@@ -5,18 +5,46 @@ import * as fastGlob from 'fast-glob';
import { Color, numberFix, render } from '../utils';
import { PerformanceTest } from './types';
+
+const args = process.argv.slice(2);
+
+const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = Color;
+
+const getRelativePath = (file: string) => {
+ return path.relative(__dirname, file);
+}
+const coloredLabeled = (label: string, file: string) => {
+ const relativeFilePath = getRelativePath(file);
+ const directory = path.dirname(relativeFilePath);
+ const fileName = path.basename(relativeFilePath);
+ return `${BG_YELLOW} ${label} ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`;
+}
+
const parentDirectory = path.resolve(__dirname, '../..');
const reportDistPath = path.join(parentDirectory, 'benchmark');
const testDir = path.join(__dirname, 'data-structures');
-const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
+const allFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
+let testFiles: string[] = [];
+if (args.length > 0) {
+ console.log(`arguments: ${args.join(' ')}`)
+
+ testFiles = allFiles.filter(file =>
+ args.every(word => file.includes(word))
+ );
+
+ console.log(`${testFiles.map(file => coloredLabeled('Matched', file)).join(`
+`)}`);
+} else {
+ testFiles = allFiles;
+}
+
const report: { [key: string]: any } = {};
let completedCount = 0;
const performanceTests: PerformanceTest[] = [];
-const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = Color;
testFiles.forEach((file: string) => {
const testName = path.basename(file, '.test.ts');
@@ -107,7 +135,7 @@ const composeReport = () => {
htmlTables // New content to be inserted
);
fs.writeFileSync(htmlFilePath, html);
- console.log(`Performance ${BOLD}${GREEN}report${END} file generated in ${BOLD}${GREEN}${reportDistPath}${END}`);
+ console.log(`Performance ${BOLD}${GREEN}report${END} file generated in file://${BOLD}${GREEN}${htmlFilePath}${END}`);
};
function replaceMarkdownContent(startMarker: string, endMarker: string, newText: string) {
@@ -135,7 +163,7 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
if (err) {
console.error(`Unable to write to ${filePath}:`, err);
} else {
- console.log(`The content has been successfully replaced in ${BOLD}${GREEN}${filePath}!${END}`);
+ console.log(`The content has been successfully replaced in file://${BOLD}${GREEN}${filePath}${END}`);
}
});
});
@@ -143,10 +171,8 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
performanceTests.forEach(item => {
const { suite, testName, file } = item;
- const relativeFilePath = path.relative(__dirname, file);
- const directory = path.dirname(relativeFilePath);
- const fileName = path.basename(relativeFilePath);
- console.log(`${BG_YELLOW} Running ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`);
+
+ console.log(coloredLabeled('Running', file));
if (suite) {
let runTime = 0;
diff --git a/test/unit/data-structures/heap/heap.test.ts b/test/unit/data-structures/heap/heap.test.ts
index accab1c..8e625f2 100644
--- a/test/unit/data-structures/heap/heap.test.ts
+++ b/test/unit/data-structures/heap/heap.test.ts
@@ -1,5 +1,5 @@
-import { FibonacciHeap, MaxHeap, MinHeap } from '../../../../src';
-import { logBigOMetricsWrap } from '../../../utils';
+import { CHeap, FibonacciHeap, MaxHeap, MinHeap } from '../../../../src';
+import { calcRunTime, logBigOMetricsWrap } from '../../../utils';
describe('Heap Operation Test', () => {
it('should numeric heap work well', function () {
@@ -257,3 +257,41 @@ describe('FibonacciHeap Stress Test', () => {
);
});
});
+
+// describe('Competitor performance compare', () => {
+// const minHeap = new MinHeap();
+// const cHeap = new CHeap();
+// const cPQ = new PriorityQueue(undefined, (a, b) => a - b);
+// const n = 10000;
+//
+// it('should add performance well', () => {
+// const heapCost = calcRunTime(() => {
+// for (let i = 0; i < n; i++) {
+// minHeap.add(i);
+// }
+// })
+//
+// console.log(`heapCost: ${heapCost}`)
+// });
+//
+// it('should add performance well', () => {
+//
+// const cHeapCost = calcRunTime(() => {
+// for (let i = 0; i < n; i++) {
+// cHeap.push(i);
+// }
+// })
+//
+// console.log(`cHeapCost: ${cHeapCost}`)
+// });
+//
+// it('should add performance well', () => {
+//
+// const cPQCost = calcRunTime(() => {
+// for (let i = 0; i < n; i++) {
+// cPQ.push(i);
+// }
+// })
+// console.log(`cPQCost: ${cPQCost}`)
+// });
+// });
diff --git a/test/utils/index.ts b/test/utils/index.ts
index 97be71e..6f522c4 100644
--- a/test/utils/index.ts
+++ b/test/utils/index.ts
@@ -5,3 +5,4 @@ export * from './json2html';
export * from './is';
export * from './console';
export * from './string';
+export * from './performanc';
diff --git a/test/utils/performanc.ts b/test/utils/performanc.ts
new file mode 100644
index 0000000..ea74095
--- /dev/null
+++ b/test/utils/performanc.ts
@@ -0,0 +1,7 @@
+import { performance } from 'perf_hooks';
+
+export const calcRunTime = (callback: (...args: any[]) => any) => {
+ const startTime = performance.now();
+ callback();
+ return performance.now() - startTime;
+}
\ No newline at end of file