[benchmark] Determine the order of magnitude for most performance tests. Report metric reductions.

This commit is contained in:
Revone 2023-11-04 17:28:52 +08:00
parent 025a90a145
commit 5af93dda72
21 changed files with 232 additions and 181 deletions

View file

@ -658,37 +658,40 @@ optimal approach to data structure design.
[//]: # (Start of Replace Section)
<div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>avl-tree</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000 add randomly</td><td>2.28</td><td>438.38</td><td>23</td><td>0.00</td><td>2.56e-5</td></tr><tr><td>1000 add & delete randomly</td><td>5.16</td><td>193.94</td><td>11</td><td>0.01</td><td>7.96e-4</td></tr><tr><td>1000 addMany</td><td>3.05</td><td>328.30</td><td>17</td><td>0.00</td><td>3.13e-4</td></tr><tr><td>1000 get</td><td>2.08</td><td>480.72</td><td>25</td><td>0.00</td><td>9.01e-5</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>32.75</td><td>30.53</td><td>9.04e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>69.59</td><td>14.37</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>42.07</td><td>23.77</td><td>8.58e-4</td></tr><tr><td>10,000 get</td><td>27.87</td><td>35.88</td><td>5.71e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>binary-tree</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000 add randomly</td><td>12.88</td><td>77.65</td><td>5</td><td>0.01</td><td>1.17e-4</td></tr><tr><td>1000 add & delete randomly</td><td>15.95</td><td>62.70</td><td>4</td><td>0.02</td><td>1.78e-4</td></tr><tr><td>1000 addMany</td><td>10.61</td><td>94.25</td><td>5</td><td>0.01</td><td>1.16e-4</td></tr><tr><td>1000 get</td><td>18.02</td><td>55.51</td><td>3</td><td>0.02</td><td>1.59e-4</td></tr><tr><td>1000 dfs</td><td>69.95</td><td>14.30</td><td>1</td><td>0.07</td><td>6.49e-4</td></tr><tr><td>1000 bfs</td><td>54.78</td><td>18.25</td><td>1</td><td>0.05</td><td>4.98e-4</td></tr><tr><td>1000 morris</td><td>37.26</td><td>26.83</td><td>2</td><td>0.04</td><td>2.16e-4</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 add randomly</td><td>12.84</td><td>77.86</td><td>1.92e-4</td></tr><tr><td>1,000 add & delete randomly</td><td>15.94</td><td>62.72</td><td>3.07e-4</td></tr><tr><td>1,000 addMany</td><td>10.59</td><td>94.45</td><td>1.67e-4</td></tr><tr><td>1,000 get</td><td>17.99</td><td>55.59</td><td>2.35e-4</td></tr><tr><td>1,000 dfs</td><td>70.17</td><td>14.25</td><td>8.83e-4</td></tr><tr><td>1,000 bfs</td><td>54.52</td><td>18.34</td><td>7.43e-4</td></tr><tr><td>1,000 morris</td><td>37.26</td><td>26.84</td><td>5.27e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>bst</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000 add randomly</td><td>2.02</td><td>496.10</td><td>25</td><td>0.00</td><td>1.56e-5</td></tr><tr><td>1000 add & delete randomly</td><td>4.60</td><td>217.31</td><td>12</td><td>0.00</td><td>4.43e-4</td></tr><tr><td>1000 addMany</td><td>2.23</td><td>448.71</td><td>24</td><td>0.00</td><td>2.96e-4</td></tr><tr><td>1000 get</td><td>2.09</td><td>479.52</td><td>25</td><td>0.00</td><td>1.27e-5</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>33.25</td><td>30.07</td><td>4.20e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>73.76</td><td>13.56</td><td>8.39e-4</td></tr><tr><td>10,000 addMany</td><td>29.96</td><td>33.38</td><td>4.40e-4</td></tr><tr><td>10,000 get</td><td>28.53</td><td>35.05</td><td>3.89e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>rb-tree</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add randomly</td><td>74.41</td><td>13.44</td><td>0.00</td></tr><tr><td>100,000 add & 1000 delete randomly</td><td>80.63</td><td>12.40</td><td>0.01</td></tr><tr><td>100,000 getNode</td><td>60.00</td><td>16.67</td><td>0.01</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>directed-graph</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000 addVertex</td><td>0.10</td><td>9871.96</td><td>501</td><td>1.01e-4</td><td>7.32e-7</td></tr><tr><td>1000 addEdge</td><td>6.48</td><td>154.29</td><td>9</td><td>0.01</td><td>0.00</td></tr><tr><td>1000 getVertex</td><td>0.05</td><td>2.17e+4</td><td>1110</td><td>4.61e-5</td><td>3.80e-7</td></tr><tr><td>1000 getEdge</td><td>24.65</td><td>40.57</td><td>3</td><td>0.02</td><td>0.01</td></tr><tr><td>tarjan</td><td>208.00</td><td>4.81</td><td>1</td><td>0.21</td><td>0.01</td></tr><tr><td>tarjan all</td><td>212.97</td><td>4.70</td><td>1</td><td>0.21</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>171.49</td><td>5.83</td><td>1</td><td>0.17</td><td>0.01</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 addVertex</td><td>0.10</td><td>9856.40</td><td>1.79e-6</td></tr><tr><td>1,000 addEdge</td><td>6.21</td><td>160.96</td><td>8.40e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.16e+4</td><td>3.85e-7</td></tr><tr><td>1,000 getEdge</td><td>22.43</td><td>44.57</td><td>0.00</td></tr><tr><td>tarjan</td><td>219.40</td><td>4.56</td><td>0.03</td></tr><tr><td>tarjan all</td><td>214.21</td><td>4.67</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>172.46</td><td>5.80</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>heap</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000 add & pop</td><td>0.34</td><td>2929.81</td><td>149</td><td>3.41e-4</td><td>2.37e-6</td></tr><tr><td>1000 fib add & pop</td><td>3.89</td><td>257.31</td><td>14</td><td>0.00</td><td>2.53e-5</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add & pop</td><td>4.63</td><td>215.75</td><td>4.05e-5</td></tr><tr><td>10,000 fib add & pop</td><td>355.10</td><td>2.82</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>doubly-linked-list</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000000 unshift</td><td>212.40</td><td>4.71</td><td>1</td><td>0.21</td><td>0.02</td></tr><tr><td>1000000 unshift & shift</td><td>172.94</td><td>5.78</td><td>1</td><td>0.17</td><td>0.03</td></tr><tr><td>1000 insertBefore</td><td>0.03</td><td>3.70e+4</td><td>1903</td><td>2.71e-5</td><td>2.38e-6</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 unshift</td><td>210.62</td><td>4.75</td><td>0.05</td></tr><tr><td>1,000,000 unshift & shift</td><td>176.63</td><td>5.66</td><td>0.04</td></tr><tr><td>1,000,000 insertBefore</td><td>288.55</td><td>3.47</td><td>0.05</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>singly-linked-list</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000 push & pop</td><td>1.75</td><td>571.73</td><td>30</td><td>0.00</td><td>5.06e-5</td></tr><tr><td>1000 insertBefore</td><td>2.30</td><td>434.82</td><td>22</td><td>0.00</td><td>5.10e-5</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 push & pop</td><td>232.24</td><td>4.31</td><td>0.03</td></tr><tr><td>10,000 insertBefore</td><td>245.58</td><td>4.07</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>max-priority-queue</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>10000 refill & poll</td><td>11.41</td><td>87.65</td><td>5</td><td>0.01</td><td>1.49e-4</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>11.62</td><td>86.09</td><td>2.24e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>deque</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000000 push</td><td>212.51</td><td>4.71</td><td>1</td><td>0.21</td><td>0.06</td></tr><tr><td>1000000 shift</td><td>24.98</td><td>40.04</td><td>3</td><td>0.02</td><td>0.00</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>223.78</td><td>4.47</td><td>0.05</td></tr><tr><td>1,000,000 shift</td><td>25.79</td><td>38.78</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>queue</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>1000000 push</td><td>41.97</td><td>23.83</td><td>2</td><td>0.04</td><td>0.01</td></tr><tr><td>1000000 push & shift</td><td>79.08</td><td>12.65</td><td>1</td><td>0.08</td><td>0.00</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>44.27</td><td>22.59</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>79.63</td><td>12.56</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>trie</span></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>executed times</th><th>sample mean (secs)</th><th>sample deviation</th></tr><tr><td>100000 push</td><td>54.24</td><td>18.44</td><td>1</td><td>0.05</td><td>7.00e-4</td></tr><tr><td>100000 getWords</td><td>96.12</td><td>10.40</td><td>1</td><td>0.10</td><td>0.00</td></tr></table></div>
<div class="content"><table><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 push</td><td>49.29</td><td>20.29</td><td>0.00</td></tr><tr><td>100,000 getWords</td><td>95.55</td><td>10.47</td><td>0.01</td></tr></table></div>
</div>
[//]: # (End of Replace Section)

View file

@ -142,7 +142,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
protected defaultOneParamCallback = (node: N) => node.key;
/**
* Creates a new instance of BinaryTreeNode with the given key and value.
* @param {BTNKey} key - The key for the new node.

View file

@ -36,7 +36,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
}
}
}
/**
* The function creates a new binary search tree node with the given key and value.
* @param {BTNKey} key - The key parameter is the key value that will be associated with

View file

@ -44,6 +44,12 @@ export class RedBlackTree {
return this._root;
}
protected _size: number = 0;
get size(): number {
return this._size;
}
/**
* The `insert` function inserts a new node with a given key into a red-black tree and fixes any
* violations of the red-black tree properties.
@ -51,7 +57,7 @@ export class RedBlackTree {
* the RBTree.
* @returns The function does not explicitly return anything.
*/
insert(key: number): void {
add(key: number): void {
const node: RBTreeNode = new RBTreeNode(key, RBTNColor.RED);
node.left = NIL;
node.right = NIL;
@ -79,20 +85,23 @@ export class RedBlackTree {
if (node.parent === null) {
node.color = RBTNColor.BLACK;
this._size++;
return;
}
if (node.parent.parent === null) {
this._size++;
return;
}
this._fixInsert(node);
this._size++;
}
/**
* The `delete` function in TypeScript is used to remove a node with a specific key from a red-black
* tree.
* @param {RBTreeNode} node - The `node` parameter is of type `RBTreeNode` and represents the current
* @param {number} key - The `node` parameter is of type `RBTreeNode` and represents the current
* node being processed in the delete operation.
* @returns The `delete` function does not return anything. It has a return type of `void`.
*/
@ -113,6 +122,7 @@ export class RedBlackTree {
}
if (z === NIL) {
this._size--;
return;
}
@ -144,6 +154,7 @@ export class RedBlackTree {
if (yOriginalColor === RBTNColor.BLACK) {
this._fixDelete(x);
}
this._size--;
};
helper(this.root);
}
@ -241,6 +252,11 @@ export class RedBlackTree {
return y;
}
clear() {
this._root = NIL;
this._size = 0;
}
print(beginRoot: RBTreeNode = this.root) {
const display = (root: RBTreeNode | null): void => {
const [lines, , ,] = _displayAux(root);

View file

@ -4,17 +4,17 @@ import {getRandomIntArray, magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const avl = new AVLTree<number>();
const {N_LOG_N} = magnitude;
const arr = getRandomIntArray(N_LOG_N, 0, N_LOG_N, true);
const {TEN_THOUSAND} = magnitude;
const arr = getRandomIntArray(TEN_THOUSAND, 0, TEN_THOUSAND, true);
suite
.add(`${N_LOG_N} add randomly`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} add randomly`, () => {
avl.clear();
for (let i = 0; i < arr.length; i++) {
avl.add(arr[i]);
}
})
.add(`${N_LOG_N} add & delete randomly`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} add & delete randomly`, () => {
avl.clear();
for (let i = 0; i < arr.length; i++) {
avl.add(arr[i]);
@ -23,11 +23,11 @@ suite
avl.delete(arr[i]);
}
})
.add(`${N_LOG_N} addMany`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} addMany`, () => {
avl.clear();
avl.addMany(arr);
})
.add(`${N_LOG_N} get`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} get`, () => {
for (let i = 0; i < arr.length; i++) {
avl.get(arr[i]);
}

View file

@ -8,13 +8,13 @@ const {N_LOG_N} = magnitude;
const arr = getRandomIntArray(N_LOG_N, 0, N_LOG_N, true);
suite
.add(`${N_LOG_N} add randomly`, () => {
.add(`${N_LOG_N.toLocaleString()} add randomly`, () => {
biTree.clear();
for (let i = 0; i < arr.length; i++) {
biTree.add(arr[i]);
}
})
.add(`${N_LOG_N} add & delete randomly`, () => {
.add(`${N_LOG_N.toLocaleString()} add & delete randomly`, () => {
biTree.clear();
for (let i = 0; i < arr.length; i++) {
biTree.add(arr[i]);
@ -23,22 +23,22 @@ suite
biTree.delete(arr[i]);
}
})
.add(`${N_LOG_N} addMany`, () => {
.add(`${N_LOG_N.toLocaleString()} addMany`, () => {
biTree.clear();
biTree.addMany(arr);
})
.add(`${N_LOG_N} get`, () => {
.add(`${N_LOG_N.toLocaleString()} get`, () => {
for (let i = 0; i < arr.length; i++) {
biTree.get(arr[i]);
}
})
.add(`${N_LOG_N} dfs`, () => {
.add(`${N_LOG_N.toLocaleString()} dfs`, () => {
for (let i = 0; i < N_LOG_N; i++) biTree.dfs();
})
.add(`${N_LOG_N} bfs`, () => {
.add(`${N_LOG_N.toLocaleString()} bfs`, () => {
for (let i = 0; i < N_LOG_N; i++) biTree.bfs();
})
.add(`${N_LOG_N} morris`, () => {
.add(`${N_LOG_N.toLocaleString()} morris`, () => {
for (let i = 0; i < N_LOG_N; i++) biTree.morris(n => n, 'pre');
});

View file

@ -4,17 +4,17 @@ import {getRandomIntArray, magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const bst = new BST<number>();
const {N_LOG_N} = magnitude;
const arr = getRandomIntArray(N_LOG_N, 0, N_LOG_N, true);
const {TEN_THOUSAND} = magnitude;
const arr = getRandomIntArray(TEN_THOUSAND, 0, TEN_THOUSAND, true);
suite
.add(`${N_LOG_N} add randomly`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} add randomly`, () => {
bst.clear();
for (let i = 0; i < arr.length; i++) {
bst.add(arr[i]);
}
})
.add(`${N_LOG_N} add & delete randomly`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} add & delete randomly`, () => {
bst.clear();
for (let i = 0; i < arr.length; i++) {
bst.add(arr[i]);
@ -23,11 +23,11 @@ suite
bst.delete(arr[i]);
}
})
.add(`${N_LOG_N} addMany`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} addMany`, () => {
bst.clear();
bst.addMany(arr);
})
.add(`${N_LOG_N} get`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} get`, () => {
for (let i = 0; i < arr.length; i++) {
bst.get(arr[i]);
}

View file

@ -0,0 +1,32 @@
import {RedBlackTree} from '../../../../src';
import * as Benchmark from 'benchmark';
import {getRandomIntArray, magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const rbTree = new RedBlackTree();
const {HUNDRED_THOUSAND} = magnitude;
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
suite
.add(`${HUNDRED_THOUSAND.toLocaleString()} add randomly`, () => {
rbTree.clear();
for (let i = 0; i < arr.length; i++) {
rbTree.add(arr[i]);
}
})
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & 1000 delete randomly`, () => {
rbTree.clear();
for (let i = 0; i < arr.length; i++) {
rbTree.add(arr[i]);
}
for (let i = 0; i < 1000; i++) {
rbTree.delete(arr[i]);
}
})
.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode`, () => {
for (let i = 0; i < arr.length; i++) {
rbTree.getNode(arr[i]);
}
});
export {suite};

View file

@ -8,24 +8,24 @@ const graph = new DirectedGraph<number, number>();
const vertexes = getRandomWords(THOUSAND);
suite
.add(`${THOUSAND} addVertex`, () => {
.add(`${THOUSAND.toLocaleString()} addVertex`, () => {
for (const v of vertexes) {
graph.addVertex(v);
}
})
.add(`${THOUSAND} addEdge`, () => {
.add(`${THOUSAND.toLocaleString()} addEdge`, () => {
for (let i = 0; i < THOUSAND; i++) {
const v1 = vertexes[getRandomIndex(vertexes)];
const v2 = vertexes[getRandomIndex(vertexes)];
graph.addEdge(v1, v2);
}
})
.add(`${THOUSAND} getVertex`, () => {
.add(`${THOUSAND.toLocaleString()} getVertex`, () => {
for (let i = 0; i < THOUSAND; i++) {
graph.getVertex(vertexes[getRandomIndex(vertexes)]);
}
})
.add(`${THOUSAND} getEdge`, () => {
.add(`${THOUSAND.toLocaleString()} getEdge`, () => {
for (let i = 0; i < THOUSAND; i++) {
graph.getEdge(vertexes[getRandomIndex(vertexes)], vertexes[getRandomIndex(vertexes)]);
}

View file

@ -3,26 +3,26 @@ import * as Benchmark from 'benchmark';
import {magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const {N_LOG_N} = magnitude;
const {TEN_THOUSAND} = magnitude;
suite
.add(`${N_LOG_N} add & pop`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
const heap = new Heap<number>({comparator: (a, b) => b - a});
for (let i = 0; i < N_LOG_N; i++) {
for (let i = 0; i < TEN_THOUSAND; i++) {
heap.add(i);
}
for (let i = 0; i < N_LOG_N; i++) {
for (let i = 0; i < TEN_THOUSAND; i++) {
heap.pop();
}
})
.add(`${N_LOG_N} fib add & pop`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} fib add & pop`, () => {
const fbHeap = new FibonacciHeap<number>();
for (let i = 1; i <= N_LOG_N; i++) {
for (let i = 1; i <= TEN_THOUSAND; i++) {
fbHeap.push(i);
}
for (let i = 1; i <= N_LOG_N; i++) {
for (let i = 1; i <= TEN_THOUSAND; i++) {
fbHeap.pop();
}
});

View file

@ -3,17 +3,17 @@ import * as Benchmark from 'benchmark';
import {magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const {LINEAR, N_LOG_N} = magnitude;
const {LINEAR} = magnitude;
suite
.add(`${LINEAR} unshift`, () => {
.add(`${LINEAR.toLocaleString()} unshift`, () => {
const list = new DoublyLinkedList<number>();
for (let i = 0; i < LINEAR; i++) {
list.unshift(i);
}
})
.add(`${LINEAR} unshift & shift`, () => {
.add(`${LINEAR.toLocaleString()} unshift & shift`, () => {
const list = new DoublyLinkedList<number>();
for (let i = 0; i < LINEAR; i++) {
@ -23,11 +23,11 @@ suite
list.shift();
}
})
.add(`${N_LOG_N} insertBefore`, () => {
.add(`${LINEAR.toLocaleString()} insertBefore`, () => {
const doublyList = new DoublyLinkedList<number>();
let midNode: DoublyLinkedListNode | null = null;
const midIndex = Math.floor(N_LOG_N / 2);
for (let i = 0; i < N_LOG_N; i++) {
const midIndex = Math.floor(LINEAR / 2);
for (let i = 0; i < LINEAR; i++) {
doublyList.push(i);
if (i === midIndex) {
midNode = doublyList.getNode(i);

View file

@ -3,25 +3,25 @@ import * as Benchmark from 'benchmark';
import {magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const {N_LOG_N} = magnitude;
const {TEN_THOUSAND} = magnitude;
suite
.add(`${N_LOG_N} push & pop`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} push & pop`, () => {
const list = new SinglyLinkedList<number>();
for (let i = 0; i < N_LOG_N; i++) {
for (let i = 0; i < TEN_THOUSAND; i++) {
list.push(i);
}
for (let i = 0; i < N_LOG_N; i++) {
for (let i = 0; i < TEN_THOUSAND; i++) {
list.pop();
}
})
.add(`${N_LOG_N} insertBefore`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} insertBefore`, () => {
const singlyList = new SinglyLinkedList<number>();
let midSinglyNode: SinglyLinkedListNode | null = null;
const midIndex = Math.floor(N_LOG_N / 2);
for (let i = 0; i < N_LOG_N; i++) {
const midIndex = Math.floor(TEN_THOUSAND / 2);
for (let i = 0; i < TEN_THOUSAND; i++) {
singlyList.push(i);
if (i === midIndex) {
midSinglyNode = singlyList.getNode(i);

View file

@ -5,7 +5,7 @@ import {magnitude} from '../../../utils';
const suite = new Benchmark.Suite();
const {TEN_THOUSAND} = magnitude;
suite.add(`${TEN_THOUSAND} refill & poll`, () => {
suite.add(`${TEN_THOUSAND.toLocaleString()} refill & poll`, () => {
const nodes = Array.from(
new Set<number>(Array.from(new Array(TEN_THOUSAND), () => Math.floor(Math.random() * TEN_THOUSAND * 100)))
);

View file

@ -6,13 +6,13 @@ export const suite = new Benchmark.Suite();
const {LINEAR} = magnitude;
suite
.add(`${LINEAR} push`, () => {
.add(`${LINEAR.toLocaleString()} push`, () => {
const deque = new Deque<number>();
for (let i = 0; i < LINEAR; i++) {
deque.push(i);
}
})
.add(`${LINEAR} shift`, () => {
.add(`${LINEAR.toLocaleString()} shift`, () => {
const deque = new Deque<number>();
for (let i = 0; i < LINEAR; i++) {
deque.push(i);

View file

@ -6,14 +6,14 @@ const suite = new Benchmark.Suite();
const {LINEAR} = magnitude;
suite
.add(`${LINEAR} push`, () => {
.add(`${LINEAR.toLocaleString()} push`, () => {
const queue = new Queue<number>();
for (let i = 0; i < LINEAR; i++) {
queue.push(i);
}
})
.add(`${LINEAR} push & shift`, () => {
.add(`${LINEAR.toLocaleString()} push & shift`, () => {
const queue = new Queue<number>();
for (let i = 0; i < LINEAR; i++) {

View file

@ -8,12 +8,12 @@ const trie = new Trie();
const randomWords = getRandomWords(HUNDRED_THOUSAND, false);
suite
.add(`${HUNDRED_THOUSAND} push`, () => {
.add(`${HUNDRED_THOUSAND.toLocaleString()} push`, () => {
for (let i = 0; i < randomWords.length; i++) {
trie.add(randomWords[i]);
}
})
.add(`${HUNDRED_THOUSAND} getWords`, () => {
.add(`${HUNDRED_THOUSAND.toLocaleString()} getWords`, () => {
for (let i = 0; i < randomWords.length; i++) {
trie.getWords(randomWords[i]);
}

View file

@ -126,11 +126,10 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
}
// Replace the old content with the new text
const updatedMarkdown =
data.slice(0, startIndex + startMarker.length) + '\n' + newText + data.slice(endIndex);
const updatedMarkdown = data.slice(0, startIndex + startMarker.length) + '\n' + newText + data.slice(endIndex);
// Try writing the modified content back to the file
fs.writeFile(filePath, updatedMarkdown, 'utf8', (err) => {
fs.writeFile(filePath, updatedMarkdown, 'utf8', err => {
if (err) {
console.error(`Unable to write to ${filePath}:`, err);
} else {
@ -145,7 +144,7 @@ performanceTests.forEach(item => {
const relativeFilePath = path.relative(__dirname, file);
const directory = path.dirname(relativeFilePath);
const fileName = path.basename(relativeFilePath);
console.log(`${BG_YELLOW}Running in${END}: ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`);
console.log(`${BG_YELLOW} Running ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`);
if (suite) {
let runTime = 0;
@ -159,8 +158,8 @@ performanceTests.forEach(item => {
'test name': benchmark.name,
'time taken (ms)': numberFix(benchmark.times.period * 1000, 2),
'executions per sec': numberFix(benchmark.hz, 2),
'executed times': numberFix(benchmark.count, 0),
'sample mean (secs)': numberFix(benchmark.stats.mean, 2),
// 'executed times': numberFix(benchmark.count, 0),
// 'sample mean (secs)': numberFix(benchmark.stats.mean, 2),
'sample deviation': numberFix(benchmark.stats.deviation, 2)
};
});

View file

@ -11,11 +11,11 @@ describe('RedBlackTree', () => {
tree = new RedBlackTree();
});
describe('insert and getNode', () => {
test('should insert and find a node in the tree', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
describe('add and getNode', () => {
test('should add and find a node in the tree', () => {
tree.add(10);
tree.add(20);
tree.add(5);
expect(tree.getNode(10)).toBeInstanceOf(RBTreeNode);
expect(tree.getNode(20)).toBeInstanceOf(RBTreeNode);
@ -23,9 +23,9 @@ describe('RedBlackTree', () => {
expect(tree.getNode(15)).toBe(null);
});
test('should insert and find nodes with negative keys', () => {
tree.insert(-10);
tree.insert(-20);
test('should add and find nodes with negative keys', () => {
tree.add(-10);
tree.add(-20);
expect(tree.getNode(-10)).toBeInstanceOf(RBTreeNode);
expect(tree.getNode(-20)).toBeInstanceOf(RBTreeNode);
@ -34,18 +34,18 @@ describe('RedBlackTree', () => {
describe('deleteNode', () => {
test('should delete a node from the tree', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.add(10);
tree.add(20);
tree.add(5);
tree.delete(20);
expect(tree.getNode(20)).toBe(null);
});
test('should handle deleting a non-existent node', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.add(10);
tree.add(20);
tree.add(5);
tree.delete(15);
expect(tree.getNode(15)).toBe(null);
@ -54,11 +54,11 @@ describe('RedBlackTree', () => {
describe('minimum', () => {
test('should find the minimum node in the tree', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(15);
tree.insert(3);
tree.add(10);
tree.add(20);
tree.add(5);
tree.add(15);
tree.add(3);
const minNode = tree.getLeftMost(tree.root);
expect(minNode.key).toBe(3);
@ -72,11 +72,11 @@ describe('RedBlackTree', () => {
describe('getRightMost', () => {
test('should find the getRightMost node in the tree', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(15);
tree.insert(25);
tree.add(10);
tree.add(20);
tree.add(5);
tree.add(15);
tree.add(25);
const maxNode = tree.getRightMost(tree.root);
expect(maxNode.key).toBe(25);
@ -90,11 +90,11 @@ describe('RedBlackTree', () => {
describe('getSuccessor', () => {
test('should find the getSuccessor of a node', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(15);
tree.insert(25);
tree.add(10);
tree.add(20);
tree.add(5);
tree.add(15);
tree.add(25);
const node = tree.getNode(15);
const successorNode = tree.getSuccessor(node);
@ -103,8 +103,8 @@ describe('RedBlackTree', () => {
});
test('should handle a node with no getSuccessor', () => {
tree.insert(10);
tree.insert(5);
tree.add(10);
tree.add(5);
const node = tree.getNode(10);
const successorNode = tree.getSuccessor(node);
@ -115,11 +115,11 @@ describe('RedBlackTree', () => {
describe('getPredecessor', () => {
test('should find the getPredecessor of a node', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(15);
tree.insert(25);
tree.add(10);
tree.add(20);
tree.add(5);
tree.add(15);
tree.add(25);
const node = tree.getNode(20);
const predecessorNode = tree.getPredecessor(node);
@ -128,8 +128,8 @@ describe('RedBlackTree', () => {
});
test('should handle a node with no getPredecessor', () => {
tree.insert(10);
tree.insert(20);
tree.add(10);
tree.add(20);
const node = tree.getNode(20);
const predecessorNode = tree.getPredecessor(node);
@ -146,69 +146,69 @@ describe('RedBlackTree', () => {
tree = new RedBlackTree();
});
it('should insert nodes into the tree', () => {
tree.insert(10);
it('should add nodes into the tree', () => {
tree.add(10);
expect(tree.getNode(10)).toBeDefined();
tree.insert(20);
tree.add(20);
expect(tree.getNode(20)).toBeDefined();
tree.insert(5);
tree.add(5);
expect(tree.getNode(5)).toBeDefined();
});
it('should delete nodes from the tree', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.add(10);
tree.add(20);
tree.add(5);
tree.delete(20);
expect(tree.getNode(20)).toBe(null);
});
it('should get the successor of a node', () => {
tree.insert(10);
tree.insert(20);
tree.add(10);
tree.add(20);
const node = tree.getNode(10);
const successor = tree.getSuccessor(node);
expect(successor?.key).toBe(20);
});
it('should get the predecessor of a node', () => {
tree.insert(10);
tree.insert(20);
tree.add(10);
tree.add(20);
const node = tree.getNode(20);
const predecessor = tree.getPredecessor(node);
expect(predecessor?.key).toBe(10);
});
it('should rotate nodes to the left', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.add(10);
tree.add(20);
tree.add(5);
const node = tree.getNode(10);
tree.insert(15);
tree.add(15);
// Verify that rotation has occurred
expect(node.left.key).toBe(5);
expect(node.right.key).toBe(20);
});
it('should rotate nodes to the right', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.add(10);
tree.add(20);
tree.add(5);
const node = tree.getNode(20);
tree.insert(25);
tree.add(25);
// Verify that rotation has occurred
expect(node.left.key).toBe(0);
expect(node.right.key).toBe(25);
});
it('should all node attributes fully conform to the red-black tree standards.', () => {
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(15);
tree.insert(21);
tree.insert(6);
tree.insert(2);
tree.add(10);
tree.add(20);
tree.add(5);
tree.add(15);
tree.add(21);
tree.add(6);
tree.add(2);
let node10F = tree.getNode(10);
let node20F = tree.getNode(20);
@ -344,31 +344,31 @@ describe('RedBlackTree', () => {
});
it('should fix the tree after insertion', () => {
tree.insert(1);
tree.insert(2);
tree.insert(5);
tree.insert(15);
tree.add(1);
tree.add(2);
tree.add(5);
tree.add(15);
const node15F = tree.getNode(15);
expect(node15F.left).toBe(NIL);
expect(node15F.right).toBe(NIL);
expect(node15F.parent).toBe(tree.getNode(5));
tree.insert(25);
tree.insert(10);
tree.insert(8);
tree.insert(28);
tree.insert(111);
tree.insert(12);
tree.add(25);
tree.add(10);
tree.add(8);
tree.add(28);
tree.add(111);
tree.add(12);
tree.delete(2);
tree.insert(22);
tree.insert(50);
tree.insert(155);
tree.insert(225);
tree.add(22);
tree.add(50);
tree.add(155);
tree.add(225);
const node225F = tree.getNode(225);
expect(node225F.left).toBe(NIL);
expect(node225F.right).toBe(NIL);
expect(node225F.parent.key).toBe(155);
tree.insert(7);
tree.add(7);
const node15S = tree.getNode(15);
expect(node15S.left.key).toBe(8);
@ -382,9 +382,9 @@ describe('RedBlackTree', () => {
const node15T = tree.getNode(15);
expect(node15T).toBe(null);
tree.insert(23);
tree.insert(33);
tree.insert(15);
tree.add(23);
tree.add(33);
tree.add(15);
const nodeLM = tree.getLeftMost();
expect(nodeLM.key).toBe(1);
@ -402,33 +402,33 @@ describe('RedBlackTree', () => {
expect(node225S.right).toBe(NIL);
expect(node225S.parent.key).toBe(155);
expect(tree.getNode(0)).toBe(null);
tree.insert(1);
tree.insert(2);
tree.insert(3);
tree.insert(4);
tree.insert(5);
tree.insert(6);
tree.insert(7);
tree.insert(8);
tree.insert(9);
tree.insert(10);
tree.insert(11);
tree.insert(12);
tree.insert(13);
tree.insert(14);
tree.insert(15);
tree.insert(16);
tree.insert(17);
tree.insert(18);
tree.insert(19);
tree.insert(110);
tree.add(1);
tree.add(2);
tree.add(3);
tree.add(4);
tree.add(5);
tree.add(6);
tree.add(7);
tree.add(8);
tree.add(9);
tree.add(10);
tree.add(11);
tree.add(12);
tree.add(13);
tree.add(14);
tree.add(15);
tree.add(16);
tree.add(17);
tree.add(18);
tree.add(19);
tree.add(110);
isDebug && tree.print();
});
it('should fix the tree after insertion and deletion', () => {
for (let i = 0; i < 100; i++) {
tree.insert(getRandomInt(-100, 1000));
tree.add(getRandomInt(-100, 1000));
tree.delete(getRandomInt(-100, 1000));
}
});

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
[{"name":"Intersection_1"},{"name":"Intersection_2"},{"name":"Intersection_3"},{"name":"Intersection_4"},{"name":"Intersection_5"},{"name":"Intersection_6"},{"name":"Intersection_7"},{"name":"Intersection_8"},{"name":"Intersection_9"},{"name":"Intersection_10"},{"name":"Intersection_11"},{"name":"Intersection_12"},{"name":"Intersection_13"},{"name":"Intersection_14"},{"name":"Intersection_15"},{"name":"Intersection_16"},{"name":"Intersection_17"},{"name":"Intersection_18"},{"name":"Intersection_19"},{"name":"Intersection_20"},{"name":"Intersection_21"},{"name":"Intersection_22"},{"name":"Intersection_23"},{"name":"Intersection_24"},{"name":"Intersection_25"},{"name":"Intersection_26"},{"name":"Intersection_27"},{"name":"Intersection_28"},{"name":"Intersection_29"},{"name":"Intersection_30"},{"name":"Intersection_31"},{"name":"Intersection_32"},{"name":"Intersection_33"},{"name":"Intersection_34"},{"name":"Intersection_35"},{"name":"Intersection_36"},{"name":"Intersection_37"},{"name":"Intersection_38"},{"name":"Intersection_39"},{"name":"Intersection_40"},{"name":"Intersection_41"},{"name":"Intersection_42"},{"name":"Intersection_43"},{"name":"Intersection_44"},{"name":"Intersection_45"},{"name":"Intersection_46"},{"name":"Intersection_47"},{"name":"Intersection_48"},{"name":"Intersection_49"},{"name":"Intersection_50"},{"name":"Intersection_51"},{"name":"Intersection_52"},{"name":"Intersection_53"},{"name":"Intersection_54"},{"name":"Intersection_55"},{"name":"Intersection_56"},{"name":"Intersection_57"},{"name":"Intersection_58"},{"name":"Intersection_59"},{"name":"Intersection_60"},{"name":"Intersection_61"},{"name":"Intersection_62"},{"name":"Intersection_63"},{"name":"Intersection_64"},{"name":"Intersection_65"},{"name":"Intersection_66"}]

View file

@ -1,6 +1,6 @@
import {UndirectedEdge, UndirectedGraph, UndirectedVertex} from '../../../../src';
import saltyVertexes from './salty-vertexes.json';
import saltyEdges from './salty-edges.json';
import saltyVertexes from './salty-vertexes.json';
import saltyEdges from './salty-edges.json';
describe('UndirectedGraph Operation Test', () => {
let graph: UndirectedGraph;
@ -151,18 +151,17 @@ describe('UndirectedGraph', () => {
it('xxx', () => {
// const start = performance.now();
const graph = new UndirectedGraph<{ name: string }, number >()
const graph = new UndirectedGraph<{name: string}, number>();
for (const v of saltyVertexes) {
graph.addVertex(v.name, v);
}
for (const e of saltyEdges) {
const [s,d] = e;
graph.addEdge( s.name, d.name, d.weight );
const [s, d] = e;
graph.addEdge(s.name, d.name, d.weight);
}
// const result = graph.getAllPathsBetween('Intersection_1','Intersection_5');
// console.log('---xxx', performance.now() - start, result)
// const result = graph.dijkstra('Intersection_1','Intersection_5', true, true);
// console.log('---xxx', performance.now() - start, result)
})
});
});