Skip to content

Commit

Permalink
perf(uniqBy): Improve performance of uniqBy
Browse files Browse the repository at this point in the history
  • Loading branch information
raon0211 committed Jun 15, 2024
1 parent 65a65ea commit 60e7974
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 8 deletions.
22 changes: 19 additions & 3 deletions benchmarks/intersection.bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(array1, array2);
});

bench('lodash', () => {
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([1, 2, 3], [2, 4]);
intersectionToolkit(array1, array2);
});

bench('lodash', () => {
intersectionLodash([1, 2, 3], [2, 4]);
intersectionLodash(array1, array2);
});
});
26 changes: 26 additions & 0 deletions benchmarks/uniqBy.bench.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
27 changes: 27 additions & 0 deletions benchmarks/uniqWith.bench.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,4 @@
"lint": "eslint ./src --ext .ts",
"format": "prettier --write ."
}
}
}
3 changes: 2 additions & 1 deletion src/array/unionBy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
14 changes: 11 additions & 3 deletions src/array/uniqBy.ts
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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());
}

0 comments on commit 60e7974

Please sign in to comment.