이 글은 모던 자바스크립트 Deep Dive를 보고 공부한 내용입니다.
자바스크립트에서 객체는 복합적인 자료구조입니다.
객체 내부에 있는 property의 수는 개수가 정해지지 않아, 객체의 크기도 정해지지 않고 동적으로 property가 추가, 삭제가 될 수 있습니다.
그래서 객체는 리터럴처럼 메모리 공간에 크기를 사전에 정의할 수 없습니다.
객체의 구현 방식은 브라우저 제조사마다 다를 수 있습니다.
그리고 객체를 생성하고 프로퍼티에 접근하는 것도 리터럴을 이용하는 것보다 비용이 많이 들기 때문에, 괜히 깔끔하게 코딩하겠다고 적은 데이터를 객체를 이용하여 선언하고 사용하면 오히려 쓸데없이 비용을 많이 쓸 수 있습니다.
(엄청 크게 차이나진 않지만..)
자바스크립트의 객체 특징
자바스크립트에서 객체는 프로퍼티 키를 인덱스로 사용하는 해시 테이블로 볼 수 있습니다.
자바스크립트에서는 클래스 없이 객체를 생성할 수 있고, 객체가 생성된 이후에 동적으로 프로퍼티와 메소드를 추가할 수 있습니다.
자바와 같은 객체지향 언어는 사전에 정의된 클래스를 기반으로 객체를 생성하는 점이 자바스크립트와 다릅니다.
이러한 자바스크립트 객체의 특징은 편리하지만, 객체 생성 및 프로퍼티 접근에 OOP 언어보다 비용이 많이 드는 단점이 있습니다.
왜냐하면 프로퍼티를 선언했을 때의 프로퍼티의 데이터 타입이나 순서가 실제로 프로퍼티 값을 접근할 때는 달라질 수 있기 때문입니다. 프로퍼티를 선언했을 때의 오프셋 값은 참조할 수 없게 되고, 이에 대한 대책이 따로 없는 한, 프로퍼티 값을 읽어야 할 때마다 프로퍼티를 찾아내야 합니다.
이러한 방식을 동적 탐색(dynamic lookup) 이라고 합니다.
그런데 V8 엔진에서는 히든 클래스라는 방식을 사용하여 프로퍼티에 접근합니다.
이 방식은 C++ 객체의 프로퍼티에 접근하는 정도의 성능을 보여줍니다.
히든 클래스
V8엔진은 새로운 객체를 생성할 때, 새로운 히든 클래스를 생성합니다.
그리고 객체에 새 프로퍼티를 추가, 삭제한다면 이전 히든 클래스를 상속받는 새 히든 클래스를 만들어 새 프로퍼티를 포함합니다.
(source : https://ui.toast.com/weekly-pick/ko_20210909)
이러한 히든 클래스의 구조를 고려한 성능 고도화
V8엔진에서 객체에 프로퍼티를 추가하면 어떻게 되는지 볼 수 있었습니다.
히든 클래스를 사용하여 프로퍼티에 접근하는 성능은 높일 수 있었으나, 프로퍼티를 추가, 삭제하면서 생기는 히든 클래스 생성에 많은 비용이 들 수밖에 없습니다.
위의 그림만 봐도, 객체에 프로퍼티를 계속 추가하면 성능이 안 좋아진다는 것을 잘 알 수 있습니다.
특정 로직에서 잦은 프로퍼티 추가가 있다면, 로직 외부에서 객체에 미리 프로퍼티를 전부 추가하여 객체를 사용하는 것이 좀 더 나은 방법이 될 수 있겠습니다.
참고한 내용
https://ui.toast.com/weekly-pick/ko_20210909
https://engineering.linecorp.com/ko/blog/v8-hidden-class/
'개발 아카이브 > Javascript' 카테고리의 다른 글
Shadow DOM - DOM을 캡슐화 하자! (0) | 2023.05.14 |
---|---|
[자바스크립트] String에 대해 알아보자. (0) | 2023.02.12 |
자바스크립트 맵 객체 (Javascript Map Object) (0) | 2022.06.15 |
[자바스크립트] console.log를 다양하게 쓰자. console 객체 (3) | 2022.01.20 |
Nomad coders - 바닐라 JS로 크롬 앱 만들기 후기 (3) | 2022.01.02 |