perf(uniqBy): Improve performance of uniqBy

This commit is contained in:
Sojin Park 2024-06-15 15:42:48 +09:00
parent 65a65ea24d
commit 60e7974127
6 changed files with 86 additions and 8 deletions

View File

@ -2,12 +2,28 @@ import { bench, describe } from 'vitest';
import { intersection as intersectionToolkit } from 'es-toolkit';
import { intersection as intersectionLodash } from 'lodash';
describe('intersection', () => {
describe('intersection, small arrays', () => {
const array1 = [1, 2, 3];
const array2 = [2, 4];
bench('es-toolkit', () => {
intersectionToolkit([1, 2, 3], [2, 4]);
intersectionToolkit(array1, array2);
});
bench('lodash', () => {
intersectionLodash([1, 2, 3], [2, 4]);
intersectionLodash(array1, array2);
});
});
describe('intersection, large arrays', () => {
const array1 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
const array2 = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
bench('es-toolkit', () => {
intersectionToolkit(array1, array2);
});
bench('lodash', () => {
intersectionLodash(array1, array2);
});
});

View File

@ -0,0 +1,26 @@
import { bench, describe } from 'vitest';
import { uniqBy as uniqByToolkit } from 'es-toolkit';
import { uniqBy as uniqByLodash } from 'lodash';
import { randomInt } from 'crypto';
describe('uniqBy, small arrays', () => {
bench('es-toolkit', () => {
uniqByToolkit([2.1, 1.2, 2.3], Math.floor);
});
bench('lodash', () => {
uniqByLodash([2.1, 1.2, 2.3], Math.floor);
});
});
describe('uniqBy, large arrays', () => {
const array = Array.from({ length: 10000 }).map(() => randomInt(0, 10000));
bench('es-toolkit', () => {
uniqByToolkit(array, Math.floor);
});
bench('lodash', () => {
uniqByLodash(array, Math.floor);
});
});

View File

@ -0,0 +1,27 @@
import { bench, describe } from 'vitest';
import { uniqWith as uniqWithToolkit } from 'es-toolkit';
import { uniqWith as uniqWithLodash } from 'lodash';
import { randomInt } from 'crypto';
describe('uniqWith, small arrays', () => {
bench('es-toolkit', () => {
uniqWithToolkit([2.1, 1.2, 2.3], (x, y) => Math.floor(x) === Math.floor(y));
});
bench('lodash', () => {
uniqWithLodash([2.1, 1.2, 2.3], (x, y) => Math.floor(x) === Math.floor(y));
});
});
describe('uniqWith, large arrays', () => {
const array = Array.from({ length: 10000 }).map(() => randomInt(0, 10000));
const comparator = (x, y) => Math.floor(x) === Math.floor(y);
bench('es-toolkit', () => {
uniqWithToolkit(array, comparator);
});
bench('lodash', () => {
uniqWithLodash(array, comparator);
});
});

View File

@ -130,4 +130,4 @@
"lint": "eslint ./src --ext .ts",
"format": "prettier --write ."
}
}
}

View File

@ -23,10 +23,11 @@ export function unionBy<T, U>(arr1: readonly T[], arr2: readonly T[], mapper: (i
for (const item of [...arr1, ...arr2]) {
const key = mapper(item);
if (!map.has(key)) {
map.set(key, item);
}
}
return [...map.values()];
return Array.from(map.values());
}

View File

@ -1,5 +1,3 @@
import { uniqWith } from './uniqWith';
/**
* Returns a new array containing only the unique elements from the original array,
* based on the values returned by the mapper function.
@ -15,5 +13,15 @@ import { uniqWith } from './uniqWith';
* ```
*/
export function uniqBy<T, U>(arr: readonly T[], mapper: (item: T) => U): T[] {
return uniqWith(arr, (item1, item2) => mapper(item1) === mapper(item2));
const map = new Map<U, T>();
for (const item of arr) {
const key = mapper(item);
if (!map.has(key)) {
map.set(key, item);
}
}
return Array.from(map.values());
}