Skip to content

Commit

Permalink
fix(utils): intersection 기능 개선 및 밴치마크 추가 (#311)
Browse files Browse the repository at this point in the history
* fix(utils): intersection 기능 개선 및 밴치마크 추가

* docs: 문서 수정

* chore: vitest coverage benchmark 파일 제외
  • Loading branch information
ssi02014 committed Jul 7, 2024
1 parent 0c4ece1 commit d077d2d
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 15 deletions.
14 changes: 13 additions & 1 deletion docs/docs/utils/array/intersection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@

기본적으로 `원시 값`에 대해서만 중복 요소를 판단하며, 필요 시 3번째 인자인 `iteratee` 함수 결과로 교차되는 요소임을 판단할 수 있습니다.

위 함수는 첫번째 배열을 기준으로 중복된 값을 제거합니다.
위 함수는 첫번째 배열을 기준으로 `중복된 값을 제거`합니다.

<br />

## Code
[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/utils/src/array/intersection/index.ts)

## Benchmark
- `hz`: 초당 작업 수
- `mean`: 평균 응답 시간(ms)

|이름|hz|mean|성능|
|------|---|---|---|
|modern-kit/intersection|338,190.49|0.0030|`fastest`|
|lodash/intersectionBy|159,624.82|0.0063|`slowest`|

- **modern-kit/intersection**
- `2.12x` faster than lodash/intersectionBy

## Interface
```ts title="typescript"
const intersection: <T, U = T>(
Expand Down
8 changes: 3 additions & 5 deletions packages/utils/src/array/intersection/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { identity } from '../../common';

import { intersectionWithDuplicates, uniq } from '..';

export const intersection = <T, U = T>(
export const intersection = <T, U>(
firstArr: T[] | readonly T[],
secondArr: T[] | readonly T[],
iteratee: (item: T) => T | U = identity,
iteratee?: (item: T) => U
) => {
const intersection = intersectionWithDuplicates(
firstArr,
secondArr,
iteratee,
iteratee
);

return uniq(intersection, iteratee);
Expand Down
22 changes: 22 additions & 0 deletions packages/utils/src/array/intersection/intersection.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { bench, describe } from 'vitest';
import { intersectionBy as intersectionByLodash } from 'lodash-es';
import { intersection } from '.';

const createTestArr = () => {
return Array.from({ length: 50 }, () => ({
id: Math.floor(Math.random() * 10),
}));
};

describe('intersection', () => {
const arr1 = createTestArr();
const arr2 = createTestArr();

bench('modern-kit/intersection', () => {
intersection(arr1, arr2, (item) => item.id);
});

bench('lodash/intersectionBy', () => {
intersectionByLodash(arr1, arr2, 'id');
});
});
18 changes: 10 additions & 8 deletions packages/utils/src/array/intersectionWithDuplicates/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { identity } from '../../common';

export const intersectionWithDuplicates = <T, U = T>(
export const intersectionWithDuplicates = <T, U>(
firstArr: T[] | readonly T[],
secondArr: T[] | readonly T[],
iteratee: (item: T) => T | U = identity,
iteratee?: (item: T) => U
) => {
const secondArrSetAppliedIteratee = new Set(secondArr.map(iteratee));

return firstArr.filter((item) =>
secondArrSetAppliedIteratee.has(iteratee(item)),
const secondArrToSet = new Set<T | U>(
iteratee ? secondArr.map(iteratee) : secondArr
);

const filterFn = iteratee
? (element: T) => secondArrToSet.has(iteratee(element))
: (element: T) => secondArrToSet.has(element);

return firstArr.filter(filterFn);
};
7 changes: 6 additions & 1 deletion packages/utils/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ export default defineConfig({
globals: true,
coverage: {
provider: 'istanbul',
exclude: ['src/storage', 'src/clipboard', 'src/file'],
exclude: [
'src/storage',
'src/clipboard',
'src/file',
'src/**/*.bench.ts',
],
},
},
});

0 comments on commit d077d2d

Please sign in to comment.