[Javascript] Array.flat() 은 느리다.

Falcon·2021년 6월 22일
31

javascript

목록 보기
5/28

🎯 Goal

  • array.flat() 메소드의 단점을 알아본다.
  • 브라우저마다 성능 차이가 있는지 비교해본다.
  • array.flat()대안을 알아본다.

What's flat()?

flat() 메서드는 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성합니다

- MDN Document

그래서 flat()이 뭐하는 앤데?
그래서 준비했다. 초간단 예제.

const arr1 = [1, 2, [3, 4]];
arr1.flat(); // default depth: 1
// [1, 2, 3, 4]
🤔 근데 뭐가 문젠데요? 처리속도가 느리다.
🤮 일반 사용자가 체감할 수 있을정도로 한국인은 짜장면 맛없는건 용서해도 느리게 오는건 용서 못해

⚙️ 테스트 환경

OSWeb Browser 1Web Browser 2
MACChrome (91.0(x86_64))Safari (14.1.1)

[Test] 2차원 배열 (원소 161개)

161
0~9의 인덱스와 원소 갯수 (25개, 13개.. 23개)를 갖는 2차원 배열을 1차원 배열로 늘어뜨려보자.

with flat

// 161 개의 데이터
console.time('flat-sort');
// falt and sort
const allRecords = response.data.records
				.flat().sort(logDatetimeCompare);
console.timeEnd('flat-sort');

sort

console.time('sort');
// only sort
const allRecords = response.data.records
				.sort(logDatetimeCompare);
console.timeEnd('sort'); 
Chrome test Chrome 기준 약 8배의 속도차이 Safari Test Safari 기준 약 10배의 속도차이

flat() 대신 쓸 수 있는 대안

.concat()

console.time('concatenation');

const allRecords =[].concat(...response.data.records)
			.sort(logDatetimeCompare);
console.timeEnd('concatenation');
// concatenation: 0.299ms
// 2회차에 0.453ms
// 3회차에 0.344ms

flat() 보다는 1.5배~2배 빠르다.
단, depth 를 1로밖에 설정할 수 없는 단점이 있다.

reduce + concat + isArray

.concat() 의 단점인 depth 제한은 없으나 속도는 당연 .concat()만 쓴것보다 느리다.

function flatDeep(arr, depth = 1) {
    return depth > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, depth - 1) : val), [])
        : arr.slice();
};

console.time('flatDeep');
const allRecords = flatDeep(response.data.records)
				.sort(logDatetimeCompare);
console.timeEnd('flatDeep');
// 0.445ms
chrome concatenation and flatDeep 크롬에서의 concat 과 reduce + concat + isArray

📊 Test 결과

단위: ms

분류ChromeSafari
flat0.1699218750.599
only sort0.026855468750.057
concat0.102050781250.344
flatDeep0.221191406250.445

배열 원소개수가 161개밖에 되지 않는데도 이런 차이를 보인다면
1,000개 10,000개 늘어날 수록..


🤔 대체 왜 이런 차이가 나타난거야? - 브라우저 엔진 개발자의 답

The key point is that the implementation of Array.prototype.flat is not at all optimized.
(중략..)
Optimizing means adding additional fast paths that take various shortcuts when possible. That work hasn't been done yet for .flat() It has been done for .concat()

- V8 Developer

👉 V8 브라우저 엔진에 .flat() 에 대한 최적화는 아직되지 않았고, .concat()에는 최적화 되었다.

✍️ 결론 한줄 요약

(Chrome, Safari 모두 2021-06-22 기준 )

간편하게 쓸 수 있는 flat() 은 브라우저에 최적화가 되있지 않은 상태이므로
[].concat() 을 사용하는 것이 속도면에서 더 유리하다.


🔗 Reference

profile
I'm still hungry

6개의 댓글

comment-user-thumbnail
2021년 6월 25일

흥미로운 글이네요! 잘 읽었습니다 :)

1개의 답글
comment-user-thumbnail
2021년 6월 25일

오... 진짜 재밌는 글이네요... reduce를 이용한 방법은 정말 좋은 거 같습니다.

1개의 답글
comment-user-thumbnail
2021년 6월 27일

유익한 정보 감사합니다! 잘 읽고 갑니다~

1개의 답글