다음과 같은 형태를 갖는 Dummy 데이터를 생성했다.
interface User {
id: number;
name: string;
email: string;
registerDate: string;
}
[
{
"id":81662,
"name":"Isaac Graham",
"email":"Russell.Watsica27@example.org",
"registerDate":"Sun Jan 23 2022 21:38:33 GMT+0900 (Korean Standard Time)"
},
{
"id":92228,
"name":"Timothy Romaguera",
"email":"Pink.Haley26@example.org",
"registerDate":"Mon Jan 24 2022 06:15:19 GMT+0900 (Korean Standard Time)"
},
{
...
}
function arrayToObject(users : User[]) {
// key: id, value: 나머지 모든 값
return users.reduce((previousObj, currentValue)=>{
return {
// previousObj has already previous key value pair
...previousObj,
[currentValue.id] : currentValue
}
}, {});
}
function arrayToMap(users : User[]) {
const userTable : Map<id, User> = new Map();
for (const user of users) {
if (userTable.has(user.id)) {
//NOTHING TO DO
} else {
userTable.set(user.id, user);
}
}
}
만들고자 하는 테이블은 사용자의 아이디를 키값으로 갖고 모든 정보를 값으로 갖는다.
테이블로 변환하는 데이터 갯수에 따라 다음과 같은 소요시간이 측정되었다.
user100
Data byte length: 14.6 kB
arrToObject: 1.907ms
arrToMap: 0.052ms
user1000
Data byte length: 147 kB
arrToObject: 186.226ms
arrToMap: 0.125ms
user10000
Data byte length: 1.46 MB
arrToObject: 39.957s
arrToMap: 3.304ms
유저 수가 1만명에 도달하니 오브젝트로의 변환은 무려 39.9초가 소요되었다.
반면에, 맵으로의 변환은 3ms 로 매우 훌륭한 성능을 보여주었다.
Node.js 버전은 14.17.5 를 사용했다.
arrToObject
메소드는 매번 데이터를 추가할 때마다 모든 데이터를 펼친다. (Spread)
...
(Spread)
return users.reduce((previousObj, currentValue)=>{
return {
...previousObj, // 💡 Spread
[currentValue.id] : currentValue
}
}, {});
이는 사전(테이블)에 데이터를 하나씩 추가할 때마다 테이블을 열고 (펼치고) 추가하고 닫는 과정을 반복하는 것이다.
배열을 오브젝트로 reduce 와 spread 를 사용해 변환하는 것 보다 Map 을 생성하는게 훨씬 빠르다.
그럼, 무조건 Map을 사용하는게 좋은가? 꼭 그렇지만은 않다.
Map 은 JSON.stringify()
로 데이터를 곧바로 변환할 수가 없기 때문에
JSON 으로 데이터를 주고받고자 할 때 별도의 파서를 사용하거나 다음과 변환 과정이 필요하다.
const map1 = new Map([
['name', 'falcon'],
['postNumber', 192]
]);
const obj = Object.fromEntries(map1);
// { name: 'falcon', postNumber: 192 }
const jsonData = JSON.stringify(obj);
따라서, 배열로부터 테이블을 생성하고자 할 때 다음과 같은 기준을 갖고 구현 방식을 결정하기로 했다.
reduce
를 활용한 배열-> 오브젝트 변환 방식은 스택오버플로우에서 찾았다.
최초 글 등록일이 2011년이라 "너무 예전 방식 써서 그런거 아니야?" 라고 할 수도 있겠지만 2019년에 등재된 다른 기술 포스트 글 에도 이와 유사한 방식의 코드 스니펫을 볼 수 있었다.
원하는 기능의 코드 스니펫을 아무데서나 찾고, IDE에서 적은 데이터로 돌려보고 "어, 돌아가네?" 하고 썼다간 이렇게 예상치 못한 경우에 당황스러운 상황이 발생할 수 있겠다는 교훈을 얻었다.