Loading...
본문 바로가기
👥
총 방문자
📖
0개 이상
총 포스팅
🧑
오늘 방문자 수
📅
0일째
블로그 운영

여러분의 방문을 환영해요! 🎉

다양한 개발 지식을 쉽고 재미있게 알려드리는 블로그가 될게요. 함께 성장해요! 😊

es-toolkit

[es-toolkit] 기여 도전하기 2일차

by 꽁이꽁설꽁돌 2025. 11. 28.
728x90
반응형

오늘도 기여를 하기 위해 여러가지를 검색하고 조사해 보았다.

 

벤치 마크 지표

각 메서드에 마다 lodash, es-toolkit/compact, es-toolkit 으로 비교하며 성능 지표를 확인할 수 있다.

확실히 es-toolkit이 우세한 성능을 보인다. 내부 동작도 이해하기가 쉽다.

 

지표 전체 이름 의미 / 해설

name 테스트 이름 벤치마크 대상 함수의 이름(lodash/add, es-toolkit/add 등)
hz operations per second 1초 동안 실행된 횟수. 높을수록 더 빠르다는 뜻
min minimum time 가장 빨리 실행된 1회 실행 시간(초 단위). 지연이 거의 0에 가까움
max maximum time 가장 느리게 실행된 1회 실행 시간. 값이 높을수록 “스파이크(지연)” 발생
mean average time 평균 실행 시간. 하지만 hz보다 정확하지 않음 (ops/sec 기준이 더 신뢰도 높음)
p75 75th percentile 전체 실행 중 75%가 이 시간 이하로 끝났다는 의미
p99 99th percentile 전체 실행 중 99%가 이 시간 이하. tail latency 분석용
p995 99.5th percentile 99.5% 구간의 실행 시간. 지연 분포를 더 자세히 확인함
p999 99.9th percentile 거의 모든 실행(99.9%)이 이 시간 이하로 끝남. 성능 안정성 핵심 지표
rme relative margin of error 상대적 오차율(±%). 낮을수록 데이터가 안정적이고 흔들림이 적다
samples number of samples 수집된 샘플 수(= 벤치마크 반복 횟수). 함수가 빠르면 더 많이 수집됨

 

 

 

또한 기여를 해보고 싶어서 따로 파서 lodash 동작과 es-toolkit 동작이 다른것을 찾던 도중 다른 동작을 찾았는데 다음과 같았다.

메서드의 동작 비교하기

chunk라는 메소드 였다. 이 메소드는 size만큼 배열을 쪼개어 이차원 배열로 반환하는 함수이다.

  {
    title: "size = 0 (Lodash returns empty array, ES throws error)",
    arr: [1, 2, 3],
    size: 0,
  },

 

es-toolkit은  Error: Size must be an integer greater than zero라는 오류를 반환했고  lodash는 빈 배열을 반환했다.

 

ES Toolkit 철학

  • 타입 안정성
  • 런타임 에러 명확화
  • 잘못된 값이 들어오면 조용한 실패를 허용하지 않음

 

따라서 결과 값 비교를 통해 찾을려면 es-toolkit/compact와 비교하는 것이 맞다.

es-toolkit/compact는 lodash와 정확히 동작이 같다.

 

사실상 이걸 다 비교하면서 결과값 다른 것을 찾기는 어렵다고 판단이 들어서 이후 메서드 하나를 분석해 보았다.

 

initial 메서드 분석

그전에 튜플에 대해 이해가 필요하므로 다음 링크를 참고하자

https://velog.io/@from_numpy/TypeScript-Tuple%ED%8A%9C%ED%94%8C

 

TypeScript - Tuple(튜플)

타입스크립트에는 자바스크립트엔 없는 굉장히(?) 유용한 타입인 “튜플”이 존재한다.이번 페이지에선 이 “튜플”의 구조 및 특징과 어떠한 장점으로써 쓰이는지 알아보고자 한다. 더욱이 “

velog.io

 

initial 메소드는 마지막 원소를 제외한 나머지 배열을 반환해주는 메서드이다.

/**
 * Returns an empty array when the input is a tuple containing exactly one element.
 *
 * @template T The type of the single element.
 * @param {[T]} arr - A tuple containing exactly one element.
 * @returns {[]} An empty array since there is only one element.
 *
 * @example
 * const array = [100] as const;
 * const result = initial(array);
 * // result will be []
 */
export function initial<T>(arr: readonly [T]): [];

/**
 * Returns an empty array when the input array is empty.
 *
 * @returns {[]} Always returns an empty array for an empty input.
 *
 * @example
 * const array = [] as const;
 * const result = initial(array);
 * // result will be []
 */
export function initial(arr: readonly []): [];

/**
 * Returns a new array containing all elements except the last one from a tuple with multiple elements.
 *
 * @template T The types of the initial elements.
 * @template U The type of the last element in the tuple.
 * @param {[...T[], U]} arr - A tuple with one or more elements.
 * @returns {T[]} A new array containing all but the last element of the tuple.
 *
 * @example
 * const array = ['apple', 'banana', 'cherry'] as const;
 * const result = initial(array);
 * // result will be ['apple', 'banana']
 */
export function initial<T, U>(arr: readonly [...T[], U]): T[];

/**
 * Returns a new array containing all elements except the last one from the input array.
 * If the input array is empty or has only one element, the function returns an empty array.
 *
 * @template T The type of elements in the array.
 * @param {T[]} arr - The input array.
 * @returns {T[]} A new array containing all but the last element of the input array.
 *
 * @example
 * const arr = [1, 2, 3, 4];
 * const result = initial(arr);
 * // result will be [1, 2, 3]
 */
export function initial<T>(arr: readonly T[]): T[];

/**
 * Returns a new array containing all elements except the last one from the input array.
 * If the input array is empty or has only one element, the function returns an empty array.
 *
 * @template T The type of elements in the array.
 * @param {T[]} arr - The input array.
 * @returns {T[]} A new array containing all but the last element of the input array.
 *
 * @example
 * const arr = [1, 2, 3, 4];
 * const result = initial(arr);
 * // result will be [1, 2, 3]
 */
export function initial<T>(arr: readonly T[]): T[] {
  return arr.slice(0, -1);
}

 

그래서 이런식으로 여러개의 타입을 지정한 이유는 여러 반환값 및 파람에 대해 타입이 다를 수 있기 때문이다.

몇 개만 골라서 살펴보면 다음과 같다.

 

/**
 * Returns a new array containing all elements except the last one from a tuple with multiple elements.
 *
 * @template T The types of the initial elements.
 * @template U The type of the last element in the tuple.
 * @param {[...T[], U]} arr - A tuple with one or more elements.
 * @returns {T[]} A new array containing all but the last element of the tuple.
 *
 * @example
 * const array = ['apple', 'banana', 'cherry'] as const;
 * const result = initial(array);
 * // result will be ['apple', 'banana']
 */
export function initial<T, U>(arr: readonly [...T[], U]): T[];

 

 

이거의 경우 아래와 같은 튜플에 대한 반환 타입을 정확히 지정하기 위해 쓰였다.

type Mixed = [number, boolean, string];
const arr: Mixed = [1, true, "a"];

 

아래와 같이 반환 값이 정확하게 나온다.

 

그에 반해 lodash는 반환 값이 기존 배열대로 나오게 된다.

 

/**
 * Returns a new array containing all elements except the last one from the input array.
 * If the input array is empty or has only one element, the function returns an empty array.
 *
 * @template T The type of elements in the array.
 * @param {T[]} arr - The input array.
 * @returns {T[]} A new array containing all but the last element of the input array.
 *
 * @example
 * const arr = [1, 2, 3, 4];
 * const result = initial(arr);
 * // result will be [1, 2, 3]
 */
export function initial<T>(arr: readonly T[]): T[];

 

이거는 보이는 그대로 타입이 하나인 배열에 대한 반환값 타입을 지정하기 위해 쓰였다.

 

 

오늘 느낀점

생각보다 열린 이슈들은 해결이 되었거나 메인 테이너 분들이 처리하셔서 기여할 거리를 찾기 어려워보인다.

그래도 여러가지를 배울 수 있어 좋은 것 같다.

반응형

'es-toolkit' 카테고리의 다른 글

[es-toolkit] 기여 도전하기 1일차  (0) 2025.11.26