data-structure-typed 1.45.1 → 1.45.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "1.45.1",
3
+ "version": "1.45.2",
4
4
  "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.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/mjs/index.js",
@@ -305,18 +305,28 @@ export class Heap<E = any> {
305
305
  * @param index - The index of the newly added element.
306
306
  */
307
307
  protected bubbleUp(index: number): void {
308
- const element = this.nodes[index];
308
+ // const element = this.nodes[index];
309
+ // while (index > 0) {
310
+ // const parentIndex = (index - 1) >> 1;
311
+ // const parent = this.nodes[parentIndex];
312
+ // if (this.comparator(element, parent) < 0) {
313
+ // this.nodes[index] = parent;
314
+ // this.nodes[parentIndex] = element;
315
+ // index = parentIndex;
316
+ // } else {
317
+ // break;
318
+ // }
319
+ // }
320
+
321
+ const item = this.nodes[index];
309
322
  while (index > 0) {
310
- const parentIndex = Math.floor((index - 1) / 2);
311
- const parent = this.nodes[parentIndex];
312
- if (this.comparator(element, parent) < 0) {
313
- this.nodes[index] = parent;
314
- this.nodes[parentIndex] = element;
315
- index = parentIndex;
316
- } else {
317
- break;
318
- }
323
+ const parent = (index - 1) >> 1;
324
+ const parentItem = this.nodes[parent];
325
+ if (this.comparator(parentItem, item) <= 0) break;
326
+ this.nodes[index] = parentItem;
327
+ index = parent;
319
328
  }
329
+ this.nodes[index] = item;
320
330
  }
321
331
 
322
332
  /**
@@ -332,8 +342,8 @@ export class Heap<E = any> {
332
342
  * @param index - The index from which to start sinking.
333
343
  */
334
344
  protected sinkDown(index: number): void {
335
- const leftChildIndex = 2 * index + 1;
336
- const rightChildIndex = 2 * index + 2;
345
+ const leftChildIndex = index << 1 | 1;
346
+ const rightChildIndex = leftChildIndex + 1;
337
347
  const length = this.nodes.length;
338
348
  let targetIndex = index;
339
349
 
@@ -8,7 +8,7 @@ const suite = new Benchmark.Suite();
8
8
  const rbTree = new RedBlackTree();
9
9
  const { HUNDRED_THOUSAND } = magnitude;
10
10
  const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
11
- const competitor = new OrderedMap<number, number>();
11
+ const cOrderedMap = new OrderedMap<number, number>();
12
12
 
13
13
  suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
14
14
  rbTree.clear();
@@ -18,9 +18,9 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
18
18
  });
19
19
 
20
20
  if (isCompetitor) {
21
- suite.add(`${HUNDRED_THOUSAND.toLocaleString()} competitor add`, () => {
21
+ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} CPT add`, () => {
22
22
  for (let i = 0; i < arr.length; i++) {
23
- competitor.setElement(arr[i], arr[i]);
23
+ cOrderedMap.setElement(arr[i], arr[i]);
24
24
  }
25
25
  });
26
26
  }
@@ -0,0 +1,142 @@
1
+ import { PriorityQueue as MJSPriorityQueue } from '../../../dist/cjs';
2
+ import { PriorityQueue as SRCPriorityQueue } from '../../../src';
3
+ import { PriorityQueue as CJSPriorityQueue } from '../../../dist/mjs';
4
+ import {
5
+ Deque as CDeque,
6
+ HashMap as CHashMap,
7
+ LinkList as CLinkedList,
8
+ OrderedMap,
9
+ PriorityQueue as CPriorityQueue,
10
+ Queue as CQueue,
11
+ Stack as CStack
12
+ } from 'js-sdsl';
13
+
14
+ import * as Benchmark from 'benchmark';
15
+ import { getRandomIntArray, magnitude } from '../../utils';
16
+ import { isCompetitor } from '../../config';
17
+
18
+ const suite = new Benchmark.Suite();
19
+ const { TEN_THOUSAND, HUNDRED_THOUSAND, LINEAR } = magnitude;
20
+ const cOrderedMap = new OrderedMap<number, number>();
21
+ const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
22
+
23
+ suite.add(`SRC ${TEN_THOUSAND.toLocaleString()} add`, () => {
24
+
25
+ const pq = new SRCPriorityQueue<number>({ comparator: (a, b) => b - a });
26
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
27
+ }).add(`CJS ${TEN_THOUSAND.toLocaleString()} add`, () => {
28
+
29
+ const pq = new CJSPriorityQueue<number>({ comparator: (a, b) => b - a });
30
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
31
+ }).add(`MJS ${TEN_THOUSAND.toLocaleString()} add`, () => {
32
+
33
+ const pq = new MJSPriorityQueue<number>({ comparator: (a, b) => b - a });
34
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
35
+ });
36
+
37
+ if (isCompetitor) {
38
+ suite.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
39
+
40
+ const pq = new CPriorityQueue<number>();
41
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
42
+ });
43
+ }
44
+
45
+ suite.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
46
+ const pq = new SRCPriorityQueue<number>({ comparator: (a, b) => b - a });
47
+
48
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
49
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
50
+ }).add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
51
+ const pq = new CJSPriorityQueue<number>({ comparator: (a, b) => b - a });
52
+
53
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
54
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
55
+ }).add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
56
+ const pq = new MJSPriorityQueue<number>({ comparator: (a, b) => b - a });
57
+
58
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
59
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
60
+ });
61
+
62
+
63
+ if (isCompetitor) {
64
+ suite.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
65
+ const pq = new CPriorityQueue<number>();
66
+
67
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
68
+ for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
69
+ })
70
+ .add(`CPT OM ${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
71
+ for (let i = 0; i < arrHundredThousand.length; i++) {
72
+ cOrderedMap.setElement(arrHundredThousand[i], arrHundredThousand[i]);
73
+ }
74
+ })
75
+ .add(`CPT HM ${TEN_THOUSAND.toLocaleString()} set`, () => {
76
+ const hm = new CHashMap<number, number>();
77
+
78
+ for (let i = 0; i < TEN_THOUSAND; i++) {
79
+ hm.setElement(i, i);
80
+ }
81
+ })
82
+ .add(`CPT HM ${TEN_THOUSAND.toLocaleString()} set & get`, () => {
83
+ const hm = new CHashMap<number, number>();
84
+
85
+ for (let i = 0; i < TEN_THOUSAND; i++) {
86
+ hm.setElement(i, i);
87
+ }
88
+ for (let i = 0; i < TEN_THOUSAND; i++) {
89
+ hm.getElementByKey(i);
90
+ }
91
+ })
92
+ .add(`CPT LL ${LINEAR.toLocaleString()} unshift`, () => {
93
+ const list = new CLinkedList<number>();
94
+
95
+ for (let i = 0; i < LINEAR; i++) {
96
+ list.pushFront(i);
97
+ }
98
+ })
99
+ .add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
100
+ const pq = new CPriorityQueue<number>();
101
+
102
+ for (let i = 0; i < TEN_THOUSAND; i++) {
103
+ pq.push(i);
104
+ }
105
+
106
+ for (let i = 0; i < TEN_THOUSAND; i++) {
107
+ pq.pop();
108
+ }
109
+ })
110
+ .add(`CPT DQ ${LINEAR.toLocaleString()} push`, () => {
111
+ const deque = new CDeque<number>();
112
+ for (let i = 0; i < LINEAR; i++) {
113
+ deque.pushBack(i);
114
+ }
115
+ })
116
+ .add(`CPT Q ${LINEAR.toLocaleString()} push`, () => {
117
+ const queue = new CQueue<number>();
118
+
119
+ for (let i = 0; i < LINEAR; i++) {
120
+ queue.push(i);
121
+ }
122
+ })
123
+ .add(`CPT ST ${LINEAR.toLocaleString()} push`, () => {
124
+ const queue = new CStack<number>();
125
+
126
+ for (let i = 0; i < LINEAR; i++) {
127
+ queue.push(i);
128
+ }
129
+ })
130
+ .add(`CPT ST ${LINEAR.toLocaleString()} push & pop`, () => {
131
+ const queue = new CStack<number>();
132
+
133
+ for (let i = 0; i < LINEAR; i++) {
134
+ queue.push(i);
135
+ }
136
+ for (let i = 0; i < LINEAR; i++) {
137
+ queue.pop();
138
+ }
139
+ });
140
+ }
141
+
142
+ export { suite };
@@ -15,7 +15,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} set`, () => {
15
15
  }
16
16
  });
17
17
  if (isCompetitor) {
18
- suite.add(`${TEN_THOUSAND.toLocaleString()} competitor set`, () => {
18
+ suite.add(`${TEN_THOUSAND.toLocaleString()} CPT set`, () => {
19
19
  const hm = new CHashMap<number, number>();
20
20
 
21
21
  for (let i = 0; i < TEN_THOUSAND; i++) {
@@ -34,7 +34,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} set & get`, () => {
34
34
  }
35
35
  });
36
36
  if (isCompetitor) {
37
- suite.add(`${TEN_THOUSAND.toLocaleString()} competitor set & get`, () => {
37
+ suite.add(`${TEN_THOUSAND.toLocaleString()} CPT set & get`, () => {
38
38
  const hm = new CHashMap<number, number>();
39
39
 
40
40
  for (let i = 0; i < TEN_THOUSAND; i++) {
@@ -15,7 +15,7 @@ suite.add(`${LINEAR.toLocaleString()} unshift`, () => {
15
15
  }
16
16
  });
17
17
  if (isCompetitor) {
18
- suite.add(`${LINEAR.toLocaleString()} competitor unshift`, () => {
18
+ suite.add(`${LINEAR.toLocaleString()} CPT unshift`, () => {
19
19
  const list = new CLinkedList<number>();
20
20
 
21
21
  for (let i = 0; i < LINEAR; i++) {
@@ -19,7 +19,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
19
19
  }
20
20
  });
21
21
  if (isCompetitor) {
22
- suite.add(`${TEN_THOUSAND.toLocaleString()} competitor add & pop`, () => {
22
+ suite.add(`${TEN_THOUSAND.toLocaleString()} CPT add & pop`, () => {
23
23
  const pq = new CPriorityQueue<number>();
24
24
 
25
25
  for (let i = 0; i < TEN_THOUSAND; i++) {
@@ -14,7 +14,7 @@ suite.add(`${LINEAR.toLocaleString()} push`, () => {
14
14
  }
15
15
  });
16
16
  if (isCompetitor) {
17
- suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
17
+ suite.add(`${LINEAR.toLocaleString()} CPT push`, () => {
18
18
  const deque = new CDeque<number>();
19
19
  for (let i = 0; i < LINEAR; i++) {
20
20
  deque.pushBack(i);
@@ -15,7 +15,7 @@ suite.add(`${LINEAR.toLocaleString()} push`, () => {
15
15
  }
16
16
  });
17
17
  if (isCompetitor) {
18
- suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
18
+ suite.add(`${LINEAR.toLocaleString()} CPT push`, () => {
19
19
  const queue = new CQueue<number>();
20
20
 
21
21
  for (let i = 0; i < LINEAR; i++) {
@@ -15,7 +15,7 @@ suite.add(`${LINEAR.toLocaleString()} push`, () => {
15
15
  }
16
16
  });
17
17
  if (isCompetitor) {
18
- suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
18
+ suite.add(`${LINEAR.toLocaleString()} CPT push`, () => {
19
19
  const queue = new CStack<number>();
20
20
 
21
21
  for (let i = 0; i < LINEAR; i++) {
@@ -34,7 +34,7 @@ suite.add(`${LINEAR.toLocaleString()} push & pop`, () => {
34
34
  }
35
35
  });
36
36
  if (isCompetitor) {
37
- suite.add(`${LINEAR.toLocaleString()} competitor push & pop`, () => {
37
+ suite.add(`${LINEAR.toLocaleString()} CPT push & pop`, () => {
38
38
  const queue = new CStack<number>();
39
39
 
40
40
  for (let i = 0; i < LINEAR; i++) {
@@ -5,18 +5,46 @@ import * as fastGlob from 'fast-glob';
5
5
  import { Color, numberFix, render } from '../utils';
6
6
  import { PerformanceTest } from './types';
7
7
 
8
+
9
+ const args = process.argv.slice(2);
10
+
11
+ const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = Color;
12
+
13
+ const getRelativePath = (file: string) => {
14
+ return path.relative(__dirname, file);
15
+ }
16
+ const coloredLabeled = (label: string, file: string) => {
17
+ const relativeFilePath = getRelativePath(file);
18
+ const directory = path.dirname(relativeFilePath);
19
+ const fileName = path.basename(relativeFilePath);
20
+ return `${BG_YELLOW} ${label} ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`;
21
+ }
22
+
8
23
  const parentDirectory = path.resolve(__dirname, '../..');
9
24
  const reportDistPath = path.join(parentDirectory, 'benchmark');
10
25
 
11
26
  const testDir = path.join(__dirname, 'data-structures');
12
- const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
27
+ const allFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
28
+ let testFiles: string[] = [];
29
+ if (args.length > 0) {
30
+ console.log(`arguments: ${args.join(' ')}`)
31
+
32
+ testFiles = allFiles.filter(file =>
33
+ args.every(word => file.includes(word))
34
+ );
35
+
36
+ console.log(`${testFiles.map(file => coloredLabeled('Matched', file)).join(`
37
+ `)}`);
38
+ } else {
39
+ testFiles = allFiles;
40
+ }
41
+
13
42
 
14
43
  const report: { [key: string]: any } = {};
15
44
 
16
45
  let completedCount = 0;
17
46
 
18
47
  const performanceTests: PerformanceTest[] = [];
19
- const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = Color;
20
48
 
21
49
  testFiles.forEach((file: string) => {
22
50
  const testName = path.basename(file, '.test.ts');
@@ -107,7 +135,7 @@ const composeReport = () => {
107
135
  htmlTables // New content to be inserted
108
136
  );
109
137
  fs.writeFileSync(htmlFilePath, html);
110
- console.log(`Performance ${BOLD}${GREEN}report${END} file generated in ${BOLD}${GREEN}${reportDistPath}${END}`);
138
+ console.log(`Performance ${BOLD}${GREEN}report${END} file generated in file://${BOLD}${GREEN}${htmlFilePath}${END}`);
111
139
  };
112
140
 
113
141
  function replaceMarkdownContent(startMarker: string, endMarker: string, newText: string) {
@@ -135,7 +163,7 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
135
163
  if (err) {
136
164
  console.error(`Unable to write to ${filePath}:`, err);
137
165
  } else {
138
- console.log(`The content has been successfully replaced in ${BOLD}${GREEN}${filePath}!${END}`);
166
+ console.log(`The content has been successfully replaced in file://${BOLD}${GREEN}${filePath}${END}`);
139
167
  }
140
168
  });
141
169
  });
@@ -143,10 +171,8 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
143
171
 
144
172
  performanceTests.forEach(item => {
145
173
  const { suite, testName, file } = item;
146
- const relativeFilePath = path.relative(__dirname, file);
147
- const directory = path.dirname(relativeFilePath);
148
- const fileName = path.basename(relativeFilePath);
149
- console.log(`${BG_YELLOW} Running ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`);
174
+
175
+ console.log(coloredLabeled('Running', file));
150
176
 
151
177
  if (suite) {
152
178
  let runTime = 0;
@@ -257,3 +257,41 @@ describe('FibonacciHeap Stress Test', () => {
257
257
  );
258
258
  });
259
259
  });
260
+
261
+ // describe('Competitor performance compare', () => {
262
+ // const minHeap = new MinHeap<number>();
263
+ // const cHeap = new CHeap<number>();
264
+ // const cPQ = new PriorityQueue<number>(undefined, (a, b) => a - b);
265
+ // const n = 10000;
266
+ //
267
+ // it('should add performance well', () => {
268
+ // const heapCost = calcRunTime(() => {
269
+ // for (let i = 0; i < n; i++) {
270
+ // minHeap.add(i);
271
+ // }
272
+ // })
273
+ //
274
+ // console.log(`heapCost: ${heapCost}`)
275
+ // });
276
+ //
277
+ // it('should add performance well', () => {
278
+ //
279
+ // const cHeapCost = calcRunTime(() => {
280
+ // for (let i = 0; i < n; i++) {
281
+ // cHeap.push(i);
282
+ // }
283
+ // })
284
+ //
285
+ // console.log(`cHeapCost: ${cHeapCost}`)
286
+ // });
287
+ //
288
+ // it('should add performance well', () => {
289
+ //
290
+ // const cPQCost = calcRunTime(() => {
291
+ // for (let i = 0; i < n; i++) {
292
+ // cPQ.push(i);
293
+ // }
294
+ // })
295
+ // console.log(`cPQCost: ${cPQCost}`)
296
+ // });
297
+ // });
@@ -5,3 +5,4 @@ export * from './json2html';
5
5
  export * from './is';
6
6
  export * from './console';
7
7
  export * from './string';
8
+ export * from './performanc';
@@ -0,0 +1,7 @@
1
+ import { performance } from 'perf_hooks';
2
+
3
+ export const calcRunTime = (callback: (...args: any[]) => any) => {
4
+ const startTime = performance.now();
5
+ callback();
6
+ return performance.now() - startTime;
7
+ }