자바스크립트 flat 함수와 리팩터링 관련해서 작성했습니다.
/**
* 일자별 API 반복 요청 함수
* @param {string[]} dateList request params로 사용될 날짜 배열
* @param {(date: string) => Promise<T[]>} fetchHandler 날짜별로 fetch 함수를 호출하는 로직이 담긴 고차함수
* @returns {Promise<T[]>} 모든 응답 결과를 1차원 배열로 가공한 값
*/
export const getAsyncAllByDate = <T>(
dateList: string[],
fetchHandler: (date: string) => Promise<T[]>
): Promise<T[]> =>
Promise.all(dateList.map((date) => fetchHandler(date) ?? [])).then((data) =>
data.reduce((acc, cur) => [...acc, ...cur])
);
위 함수는 업무중 구현한 일자별 API 반복 요청 함수입니다.
리팩터링을 고민하던중 고차원 배열을 평탄화된 새로운 배열로 만들어주는 flat() 알게되었고,
이를 2차원 배열을 1차원 배열로 가공하는 과정에 적용하고자 했습니다.
// before
data.reduce((acc, cur) => [...acc, ...cur]);
// after
data.flat();
아래 변수는 배열안에 배열이있는 2차원 배열 이지만
flat() 사용하면 중첩된 배열이 사라진 1차원 배열을 가질 수 있게 된다.
const array = [[1,2],[3,4],[5,6]];
console.log(array.flat());
// [1,2,3,4,5,6]
2차원보다 더 중첩 되어있다면 depth 옵션을 주면 되고,
기본값은 1 이다.
const array = [[1,[2,3]],[4,[5,6]]];
console.log(array.flat(2));
// [1,2,3,4,5,6]
몇번 중첩 되었는지 알 수 없다면 Infinity를 입력하면 된다.
const array = [[1,[2,[[3],4],[5],6]]];
console.log(array.flat(Infinity));
// [1,2,3,4,5,6]
짧아지고 깔끔 해지긴 했는데...
성능도 더 좋아졌을까?
reduce() 결과
flat() 결과
아쉽게도 성능이 안좋아졌다 😭
왜그럴까?

flat()과 cancat()의 성능 비교에 대한 질문에 브라우저 엔진 개발자의 답변을 보면
V8 브라우저 엔진에 flat() 에 대한 최적화가 아직되지 않아서 성능저하가 발생한걸로 보여진다.
하지만 마지막 문장을 보면
대부분의 애플리케이션은 수백만 개의 요소로 배열을 평탄화하는데 시간을 소비하지 않으며
소규모 배열(수십 개, 수백 개, 수천 개)의 경우 노이즈 레벨 이하의 차이가 발생
따라서 작성한 함수는 수십만까지 가지 않는 순회 함수이기 때문에 가독성을 위해 리팩터링 하는게 더 좋아보인다.
항상 리팩터링할때 성능 체크가 필수요소 인거 같다.
순회와 같은 성능에 큰영향이 있을만한 함수는 성능 테스트도 같이 삽입되어 있으면 좋을 것 같다는 생각이 들었다.
자동으로 성능까지 테스트 해볼수있는 방법을 고민해봐야겠다.