├── DeletingQueue.js
├── LICENSE
├── MapQueue.js
├── MapUndefQueue.js
├── README.md
├── SplicingQueue.js
├── UndefinedQueue.js
└── test.js
/DeletingQueue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = class Queue {
4 | constructor() {
5 | this.items = {};
6 | this.headIndex = 0;
7 | this.tailIndex = 0;
8 | }
9 |
10 | enqueue(item) {
11 | this.items[this.tailIndex] = item;
12 | this.tailIndex++;
13 | }
14 |
15 | dequeue() {
16 | const item = this.items[this.headIndex];
17 | delete this.items[this.headIndex];
18 | this.headIndex++;
19 | return item;
20 | }
21 |
22 | peek() {
23 | return this.items[this.headIndex];
24 | }
25 |
26 | get length() {
27 | return this.tailIndex - this.headIndex;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2021, Dmitri Pavlutin
2 | Copyright © 2021, Michael J. Ryan
3 |
4 | Permission to use, copy, modify, and/or distribute this software for any
5 | purpose with or without fee is hereby granted, provided that the above
6 | copyright notice and this permission notice appear in all copies.
7 |
8 | THE SOFTWARE IS PROVIDED “AS IS” AND ISC DISCLAIMS ALL WARRANTIES WITH
9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 | AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
12 | FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
13 | NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
14 | THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 |
--------------------------------------------------------------------------------
/MapQueue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = class Queue {
4 | constructor() {
5 | this.items = new Map();
6 | this.headIndex = 0;
7 | this.tailIndex = 0;
8 | }
9 |
10 | enqueue(item) {
11 | this.items.set(this.tailIndex, item);
12 | this.tailIndex++;
13 | }
14 |
15 | dequeue() {
16 | const item = this.items.get(this.headIndex);
17 | this.items.delete(this.headIndex);
18 | this.headIndex++;
19 | return item;
20 | }
21 |
22 | peek() {
23 | return this.items.get(this.headIndex);
24 | }
25 |
26 | get length() {
27 | return this.tailIndex - this.headIndex;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/MapUndefQueue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = class Queue {
4 | constructor() {
5 | this.items = new Map();
6 | this.headIndex = 0;
7 | this.tailIndex = 0;
8 | }
9 |
10 | enqueue(item) {
11 | this.items.set(this.tailIndex, item);
12 | this.tailIndex++;
13 | }
14 |
15 | dequeue() {
16 | const item = this.items.get(this.headIndex);
17 | this.items.set(this.headIndex, undefined);
18 | this.headIndex++;
19 | return item;
20 | }
21 |
22 | peek() {
23 | return this.items.get(this.headIndex);
24 | }
25 |
26 | get length() {
27 | return this.tailIndex - this.headIndex;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Testing Queue Implementations
2 |
3 | Was curious about the performance of a few different queue implementation options.
4 |
5 | ## Queue Implementations
6 |
7 | #### SplicingQueue
8 |
9 | - store: `Array`
10 | - index: natural
11 | - dequeue: `splice()` method
12 |
13 | #### DeletingQueue ([link](https://dmitripavlutin.com/javascript-queue/))
14 |
15 | - store: `Object`
16 | - index: manual
17 | - dequeue: `delete o[index]`
18 |
19 | #### UndefinedQueue
20 |
21 | - store: `Object`
22 | - index: manual
23 | - dequeue: `o[index] = undefined`
24 |
25 | #### MapQueue
26 |
27 | - store: `Map`
28 | - index: manual
29 | - dequeue: `m.delete(index)`
30 |
31 | #### MapUndefQueue
32 |
33 | - store: `Map`
34 | - index: manual
35 | - dequeue: `m.set(index, undefined)`
36 |
37 |
38 |
39 | ## Results
40 |
41 | | Implementation \ Iterations | 10000 | 100000 |
42 | | --------------------------- | ---------- | ---------- |
43 | | SplicingQueue | 10.07ms | 3,054.83ms |
44 | | DeletingQueue | 5.78ms | 13.26ms |
45 | | **UndefinedQueue** | **5.28ms** | **9.25ms** |
46 | | MapQueue | 6.72ms | 19.55ms |
47 | | MapUndefQueue | 6.67ms | 17.27ms |
48 |
49 |
50 |
51 | #### System
52 |
53 | - CPU: Ryzen R9 3950X
54 | - RAM: 32GB DDR4 @ 3200mhz
55 | - Windows Desktop with misc background applications.
56 |
57 | #### Environment
58 |
59 | - WSL2 (Windows 10)
60 | - Ubuntu 20.04 LTS
61 | - Node 14.16.0
62 |
63 |
64 |
65 | ### Raw
66 |
67 | ```
68 | ❯ node test UndefinedQueue 10000 \
69 | && node test UndefinedQueue 10000 \
70 | && node test UndefinedQueue 10000 \
71 | && node test UndefinedQueue 100000 \
72 | && node test UndefinedQueue 100000 \
73 | && node test UndefinedQueue 100000 \
74 | && node test DeletingQueue 10000 \
75 | && node test DeletingQueue 10000 \
76 | && node test DeletingQueue 10000 \
77 | && node test DeletingQueue 100000 \
78 | && node test DeletingQueue 100000 \
79 | && node test DeletingQueue 100000 \
80 | && node test MapUndefQueue 10000 \
81 | && node test MapUndefQueue 10000 \
82 | && node test MapUndefQueue 10000 \
83 | && node test MapUndefQueue 100000 \
84 | && node test MapUndefQueue 100000 \
85 | && node test MapUndefQueue 100000 \
86 | && node test MapQueue 10000 \
87 | && node test MapQueue 10000 \
88 | && node test MapQueue 10000 \
89 | && node test MapQueue 100000 \
90 | && node test MapQueue 100000 \
91 | && node test MapQueue 100000 \
92 | && node test SplicingQueue 10000 \
93 | && node test SplicingQueue 10000 \
94 | && node test SplicingQueue 10000 \
95 | && node test SplicingQueue 100000 \
96 | && node test SplicingQueue 100000 \
97 | && node test SplicingQueue 100000
98 |
99 | Starting UndefinedQueue 10000
100 | 0s 5.3198ms
101 |
102 | Starting UndefinedQueue 10000
103 | 0s 5.2588ms
104 |
105 | Starting UndefinedQueue 10000
106 | 0s 5.2547ms
107 |
108 | Starting UndefinedQueue 100000
109 | 0s 9.3543ms
110 |
111 | Starting UndefinedQueue 100000
112 | 0s 9.1768ms
113 |
114 | Starting UndefinedQueue 100000
115 | 0s 9.2075ms
116 |
117 | Starting DeletingQueue 10000
118 | 0s 5.8258ms
119 |
120 | Starting DeletingQueue 10000
121 | 0s 5.8019ms
122 |
123 | Starting DeletingQueue 10000
124 | 0s 5.6946ms
125 |
126 | Starting DeletingQueue 100000
127 | 0s 13.1500ms
128 |
129 | Starting DeletingQueue 100000
130 | 0s 13.3311ms
131 |
132 | Starting DeletingQueue 100000
133 | 0s 13.2906ms
134 |
135 | Starting MapUndefQueue 10000
136 | 0s 6.6675ms
137 |
138 | Starting MapUndefQueue 10000
139 | 0s 6.8331ms
140 |
141 | Starting MapUndefQueue 10000
142 | 0s 6.5056ms
143 |
144 | Starting MapUndefQueue 100000
145 | 0s 18.1364ms
146 |
147 | Starting MapUndefQueue 100000
148 | 0s 16.8714ms
149 |
150 | Starting MapUndefQueue 100000
151 | 0s 16.8159ms
152 |
153 | Starting MapQueue 10000
154 | 0s 6.6567ms
155 |
156 | Starting MapQueue 10000
157 | 0s 6.7161ms
158 |
159 | Starting MapQueue 10000
160 | 0s 6.7881ms
161 |
162 | Starting MapQueue 100000
163 | 0s 20.0687ms
164 |
165 | Starting MapQueue 100000
166 | 0s 19.3000ms
167 |
168 | Starting MapQueue 100000
169 | 0s 19.2826ms
170 |
171 | Starting SplicingQueue 10000
172 | 0s 10.0839ms
173 |
174 | Starting SplicingQueue 10000
175 | 0s 10.0796ms
176 |
177 | Starting SplicingQueue 10000
178 | 0s 10.0315ms
179 |
180 | Starting SplicingQueue 100000
181 | 3s 51.1512ms
182 |
183 | Starting SplicingQueue 100000
184 | 3s 60.5138ms
185 |
186 | Starting SplicingQueue 100000
187 | 3s 52.8187ms
188 | ```
189 |
190 | ## Licenses
191 |
192 | [ISC](https://www.isc.org/licenses/) license.
193 |
194 | Copyright © 2021, Dmitri Pavlutin
195 | Copyright © 2021, Michael J. Ryan
196 |
197 | Permission to use, copy, modify, and/or distribute this software for any
198 | purpose with or without fee is hereby granted, provided that the above
199 | copyright notice and this permission notice appear in all copies.
200 |
201 | THE SOFTWARE IS PROVIDED “AS IS” AND ISC DISCLAIMS ALL WARRANTIES WITH
202 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
203 | AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
204 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
205 | FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
206 | NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
207 | THE USE OR PERFORMANCE OF THIS SOFTWARE.
208 |
--------------------------------------------------------------------------------
/SplicingQueue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = class Queue {
4 | constructor() {
5 | this._items = [];
6 | }
7 |
8 | enqueue(item) {
9 | this._items.push(item);
10 | }
11 |
12 | dequeue() {
13 | return this._items.splice(0, 1)?.[0];
14 | }
15 |
16 | peek() {
17 | // O(1)
18 | return this._items[0];
19 | }
20 |
21 | get length() {
22 | // O(n)
23 | return this._items.length;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/UndefinedQueue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = class Queue {
4 | constructor() {
5 | this.items = {};
6 | this.headIndex = 0;
7 | this.tailIndex = 0;
8 | }
9 |
10 | enqueue(item) {
11 | this.items[this.tailIndex] = item;
12 | this.tailIndex++;
13 | }
14 |
15 | dequeue() {
16 | const item = this.items[this.headIndex];
17 | this.items[this.headIndex] = undefined;
18 | this.headIndex++;
19 | return item;
20 | }
21 |
22 | peek() {
23 | return this.items[this.headIndex];
24 | }
25 |
26 | get length() {
27 | return this.tailIndex - this.headIndex;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Usage:
3 | * node test QUEUENAME ITERATIONS
4 | *
5 | * ex:
6 | * node test DeletingQueue 100000 && node test UndefinedQueue 100000
7 | *
8 | * os.freemem() - was trying to determine memory usage, but the results
9 | * vary too wildly to be worth recording.
10 | */
11 | "use strict";
12 |
13 | const assert = require("assert");
14 | // const os = require("os");
15 |
16 | const formatNum = (n) =>
17 | n.toString().replace(/\B(?