Instantly share code, notes, and snippets.

Embed
What would you like to do?
Benchmark of "uniq" for Array in JavaScript
// License: MIT
// Original Author: YUKI "Piro" Hiroshi <yuki@clear-code.com>
// confirmed at Firefox 64
async function test(times, length) {
function uniqByIndexOf(array) {
const uniquedArray = [];
for (const elem of array) {
if (uniquedArray.indexOf(elem) < 0)
uniquedArray.push(elem);
}
return uniquedArray;
}
function uniqByIncludes(array) {
const uniquedArray = [];
for (const elem of array) {
if (!uniquedArray.includes(elem))
uniquedArray.push(elem);
}
return uniquedArray;
}
function uniqByFilter(array) {
return array.filter(function(elem, index, self) {
return self.indexOf(elem) === index;
});
}
function uniqByFilterArrow(array) {
return array.filter((elem, index, self) => self.indexOf(elem) === index);
}
function uniqByMap(array) {
const knownElements = new Map();
const uniquedArray = [];
for (const elem of array) {
if (knownElements.has(elem))
continue;
uniquedArray.push(elem);
knownElements.set(elem, true);
}
return uniquedArray;
}
function uniqByMapKeys(array) {
const knownElements = new Map();
for (const elem of array) {
knownElements.set(elem, true);
}
return Array.from(knownElements.keys());
}
function uniqBySet(array) {
return Array.from(new Set(array));
}
function uniqBySetAndSpread(array) {
return [...new Set(array)];
}
function prepareArray(length) {
const array = [];
for (let i = 0; i < length; i++) {
array.push(parseInt(Math.random() * (length / 10)));
}
return array;
}
const methods = [uniqByIndexOf, uniqByIncludes, uniqByFilter, uniqByFilterArrow, uniqByMap, uniqByMapKeys, uniqBySet, uniqBySetAndSpread];
const results = [];
for (const uniq of methods) {
const start = Date.now();
const array = prepareArray(length);
for (let i = 0; i < times; i++) {
uniq(Array.from(array));
}
const delta = Date.now() - start;
console.log(`${times}times, length=${length}, ${uniq.name}`, delta);
results.push(delta);
await new Promise(resolve => setTimeout(resolve, 10));
}
return results;
}
(async () => {
const methods = ',uniqByIndexOf,uniqByIncludes,uniqByFilter,uniqByFilterArrow,uniqByMap,uniqByMapKeys,uniqBySet,uniqBySetAndSpread';
async function runForTimes(length, start, step) {
const results = [methods];
for (let i = 0, maxi = 5; i < maxi; i++) {
const times = start + (step * i);
results.push(times + ',' + (await test(times, length)).join(','));
}
console.log(results.join('\n'));
}
console.log('tests with small array');
await runForTimes(10, 100000, 100000);
console.log('tests with middle array');
await runForTimes(300, 2500, 2500);
console.log('tests with large array');
await runForTimes(5000, 100, 100);
async function runForLength(times, start, step) {
const results = [methods];
for (let i = 0, maxi = 10; i < maxi; i++) {
const length = start + (step * i);
results.push(length + ',' + (await test(times, length)).join(','));
}
console.log(results.join('\n'));
}
console.log('tests with increasing length');
await runForLength(5000, 100, 100);
console.log('done');
})();
uniqByIndexOf uniqByIncludes uniqByFilter uniqByFilterArrow uniqByMap uniqByMapKeys uniqBySet uniqBySetAndSpread
100 33 34 58 34 84 117 72 85
300 201 194 223 224 290 303 195 181
500 320 351 394 497 411 535 335 362
700 555 596 759 914 572 669 393 393
900 782 865 1076 1402 719 814 526 508
1100 1091 1287 1735 1941 934 1298 660 670
1300 1432 1626 2127 2686 1162 1435 810 766
1500 1742 2065 2421 3273 1245 1393 1035 900
1700 2135 2517 3576 3814 1357 1835 1072 1048
1900 2179 3071 4667 5022 2395 2081 1321 1216
uniqByIndexOf uniqByIncludes uniqByFilter uniqByFilterArrow uniqByMap uniqByMapKeys uniqBySet uniqBySetAndSpread
100 28 37 24 24 44 56 36 29
200 48 51 68 61 94 102 72 58
300 94 144 144 118 142 167 110 103
400 125 143 221 193 218 312 131 129
500 156 205 260 221 254 256 156 155
600 219 245 305 331 269 447 202 207
700 257 310 470 366 314 373 227 232
800 334 361 583 485 343 394 248 250
900 355 403 699 521 405 449 300 283
1000 485 484 984 681 437 511 367 326
uniqByIndexOf uniqByIncludes uniqByFilter uniqByFilterArrow uniqByMap uniqByMapKeys uniqBySet uniqBySetAndSpread
100 121 161 335 272 49 53 39 67
200 239 310 648 508 92 146 74 70
300 459 572 1076 839 161 165 114 103
400 531 627 1314 1019 184 213 151 139
500 643 779 1689 1307 225 255 184 173
uniqByIndexOf uniqByIncludes uniqByFilter uniqByFilterArrow uniqByMap uniqByMapKeys uniqBySet uniqBySetAndSpread
2500 46 54 75 59 77 83 53 53
5000 109 110 134 120 144 180 133 105
7500 144 160 213 187 217 242 166 178
10000 192 211 271 243 286 341 214 216
12500 215 244 324 292 349 457 268 275
uniqByIndexOf uniqByIncludes uniqByFilter uniqByFilterArrow uniqByMap uniqByMapKeys uniqBySet uniqBySetAndSpread
100000 104 96 90 84 182 253 249 211
200000 180 179 181 171 387 539 487 361
300000 313 286 249 300 577 741 618 540
400000 344 351 335 342 923 984 847 728
500000 445 458 417 435 1130 1246 1006 888
@piroor

This comment has been minimized.

Copy link
Owner

piroor commented Dec 27, 2018

graph:
small-array.png
middle-array.png
large-array.png
increasing-length.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment