V8 히든클래스

자바스크립트는 동적 언어로 객체에서 속성을 즉시 추가하거나 제거할 수 있다. 그러나 이러한 동적조회는 성능 저하의 원인이다.

동적 조회

동적 언어에서 객체에 속성을 추가하거나 제거할 경우 선형탐색 후 속성에 접근하게 된다. 이럴 경우 프로퍼티에 접근할 경우 객체의 모든 속성에 대한 탐색이 필요하다.

해결방안

V8엔진은 이를 해결하기 위해 히든클래스라는 개념을 도입하였다.
자바스크립트에서 객체를 생성할 경우 새로운 히든 클래스를 생성한다.

예시

아래의 코드는 빈 객체를 생성하는 코드이다.

1
const object1 = {};

V8은 이 코드를 기반으로 새로운 히든 클래스를 만든다.
편의상 객체로 표현하였다.

1
c01 = {};

아래의 코드는 object1 객체에 속성을 추가하는 코드이다.

1
object1.name = "박성현";

아래의 코드를 실행할 경우 V8은 이전 히든클래스(c01)의 모든 프로퍼티를 상속하여 새로운 히든클래스(c02)를 만든다.

그 후 object1은 c02를 참조하고 V8은 c01을 계속해서 참조한다.

이렇게 되면 컴파일러가 프로퍼티 이름에 접근할 때 offset을 통해 접근하여 사전형 탐색을 우회할 수 있다.

1
2
c01 = {}; //V8이 참조중
c02 = { offset0: name }; //object1이 참조중

아래의 코드는 object1 객체에 또 다른 속성을 추가하는 코드이다.

1
object1.age = 20;
1
2
3
c01 = {}; //V8이 참조중
c02 = { offset0: name };
c03 = { offset0: name, offset1: age }; //object1이 참조중

V8은 이러한 히든 클래스를 재사용한다.
만약 다음과 같은 코드를 작성하였을 경우 c01을 재사용 한다.

1
object2 = {};
1
2
3
c01 = {}; //V8과 object2가 참조중
c02 = { offset0: name };
c03 = { offset0: name, offset1: age }; //object1이 참조중

하지만 다음과 같이 name,age 외의 프로퍼티를 추가하여 c03을 재사용할 수 없는 경우 다시 새로운 클래스를 만든다.
V8은 c02를 재사용하여 새로운 트랜지션 트리를 만들고 히든클래스인 c4를 만들어 추가한다.

1
object2.school = "konkuk univ";
1
2
3
4
c01 = {}; //V8과 object2가 참조중
c02 = { offset0: name };
c03 = { offset0: name, offset1: age }; //object1이 참조중
c04 = { offset0: name, offset1: school }; //object2가 참조중, c02와 연결된다

성능 개선 방안

V8엔진의 히든클래스를 이용하여 성능개선을 하기 위해선 동적 프로퍼티 추가를 줄여야한다.

예를들어 반복문 안에서 객체의 동적 프로퍼티를 추가하는 대신 반복문 외부에서 프로퍼티를 만들어 사용하는 것이 좋다.

즉 기존의 히든클래스를 재사용할 떄 성능이 향상된다.

ref

V8의 히든 클래스 이야기
자바스크립트 성능의 비밀 (V8과 히든 클래스)
Fast properties in V8

댓글