├── 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(?