여기서 데이터도 변경해 보고, 벤치마크 직접 돌려볼 수 있다.

내가 넣은 데이터는 요녀석이었다.

{a: "hello", c: "test", po: 33, arr: [1, 2, 3, [4, [5, 6]]], anotherObj: {a: [1, 2, 3, [4, [5, 6]]], str: "whazzup"}};
 

JSBEN.CH Performance Benchmarking Playground for JavaScript

 

jsben.ch

 

결과를 그냥 말해주자면 아래의 사진과 같다.

Object.assign이 가장 빠르며, 유의미하게 lodash의 _.cloneDeep이 가장 느리다.

 

내가 구현한 커스텀 깊은 복사 메서드는 아래와 같다. 사이사이에 주석을 잘 달아놨으니, 읽어보면 이해가 잘 갈 것이다.

그래도 간단히 설명을 덧붙이자면 재귀적으로 구현했다. 배열이거나 객체면 깊게 들어가서 잘 반환해 주는 식이다.

function cloneDeep(obj) {
  if (typeof obj !== 'object' || obj === null) {
    // 객체가 아니거나 null인 경우 그대로 반환
    return obj;
  }

  if (Array.isArray(obj)) {
    // 배열인 경우 빈 배열 생성 후 요소들을 재귀적으로 복사
    return obj.map(item => cloneDeep(item));
  } else {
    // 객체인 경우 빈 객체 생성 후 속성들을 재귀적으로 복사
    const clonedObj = {};
    for (const key in obj) {
      clonedObj[key] = cloneDeep(obj[key]);
    }
    return clonedObj;
  }
}

lodash가 워낙에 무겁다고 해서 직접 구현도 해보고, 비교도 해봤는데 진짜 차이가 꽤 크긴 하다.

물론 내 구현 방식을 lodash의 deepClone과 비교해 봤을 때 빠진 부분이 분명히 많겠지만(정규식이라던가), 그래도 내가 만든 재귀적인 함수에서도 웬만한 데이터에서의 깊은 복사는 다 할 수 있을 것으로 예상이 된다.

JSON 객체를 이용한 깊은복사 역시 number, string, boolean, object, array, null 에서만 복사가 가능하다. 이를 생각해봤을 때 내가 만든 재귀와 비교해볼만한 메서드는 stringify + parse이며, 직접 구현해서 사용하면 훨씬 편하다는 것을 알 수 있다.

Object.assign은 얕은 복사니까 굳이 신경 쓰진 않겠다.. 그냥 얼마나 빠른지만 궁금했다.

 

결론

1. 귀찮아도 JSON으로 깊은 복사는 지양하자.

 

2. 재귀는 아직 내겐 '감'으로 짜는 영역인듯하다. mock 데이터 하나 머리로 떠올리고 함수 하나하나 내부로 들어가서 상상으로 돌려보면 골치 아프다. 최소한 펜이랑 종이는 있어야 할 듯

+ Recent posts