회고록 블로그

V8 엔진의 히든 클래스 본문

2. 프로그래밍 언어 공부/JavaScript

V8 엔진의 히든 클래스

김간장 2022. 6. 12. 22:22

※ 필자는 초초초보입니다.

   틀린 내용은 언제든지 댓글 등 부탁드립니다.

 


 

모던 자바스크립트 Deep Dive 책 읽다가 히든 클래스에 대한 언급이 잠깐 나와서 한번 찾아봤다.

 

✅ V8 엔진

위키백과에 따르면 구글에서 개발한 자바스크립트 엔진이며, 웨 브라우저를 만드는데 기반을 제공하는 오픈 소스 자바스크립트 엔진이라고 한다.

구글 크롬 브라우저와 안드로이드 브라우저에 탑재되어 있고,

Node.js 또한 크롬 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임이다.

 

 

V8 공식 사이트에서는 다음과 같은 특징이 있다고 한다.

- V8 엔진은 C++로 작성되었다.

- 고성능 자바스크립트, 웹어셈블리어 엔진이다.

- 크롬 및 Node.js 등에서 사용된다.

 

 

✅ 동적 타이핑 언어

자바, C++과 같은 클래스 기반 객체지향 프로그래밍 언어는 클래스를 기반으로 객체(인스턴스)가 만들어지며

클래스를 통해 메서드, 변수(?) 등을 미리 정해놓고 그대로 객체(인스턴스)를 생성하게 된다.

객체가 생성된 이후에 클래스 내부의 멤버를 삭제, 추가할 수는 없지만

객체 생성과 각 멤버에 접근하는 비용이 상대적으로 덜 든다고 한다.

 

하지만 자바스크립트는 클래스 없이 객체를 생성하는 객체지향 프로그래밍 언어이며,

이러한 특징 덕분에 객체 생성 이후에도 프로퍼티와 메서드를 추가할 수 있지만

대신 성능 면에서는 이론적으로 클래스 기반 객체지향 프로그래밍 언어보다 객체의 생성과 프로퍼티 접근에 비용이 많이 든다고 한다.

 

 

각각 이러한 장단점이 있고,

자바, C++ 등은 컴파일 시 컴파일 시 타입이 정해지는 정적 타이핑 언어라고 하며

자바스크립트, 파이썬 등은 런타임 시 타입이 정해지는 동적 타이핑 언어라고 한다.

 

정리하자면, 동적 타이핑 언어는 객체의 프로퍼티에 접근하는 속도 면에서 정적 타이핑 언어와 비교를 하면 조금 불리하다고 할 수 있다.

(이론상으로 말하는 것이다. 이론상!)

 

어쨌든 동적 타이핑 언어의 이런 특징 덕분에 프로퍼티에 접근하려면 동적 탐색이 필요하다.

 

 

✅ 동적탐색

영문으로는 dynamic lookup라고 한다.

 

정적 탐색이 있고, 동적 탐색이 있는데

위에서 말했듯이 동적 타이핑 언어의 특징 때문에 프로퍼티에 접근하려면 일반적으로 동적 탐색 방식을 사용한다.

 

Java 등 정적 타이핑 언어는 객체가 생성된 이후부터는 메모리에 적재되었고,

프로퍼티나 메서드가 추가되거나 삭제되지 않는다.

 

따라서 프로퍼티를 선언할 때 어딘가에 테이블(?)을 만들어놓고, 거기에 오프셋을 저장해놓으면

프로퍼티에 접근하는 코드가 포함된 소스코드를 컴파일 할 때,

해당 테이블을 참고해서 오프셋(위치)을 찾아놓고 탕탕 결정해놓으면

런타임 시 해당 오프셋 값을 그대로 사용할 수 있고 덕분에 빠르게 프로퍼티에 접근할 수 있게 된다.

 

런타임 과정에서 프로퍼티나 메서드가 추가될 일이 없기 때문에 만들어놓은 테이블(?)은 업데이트 되지도 않는다.

이런 과정이 정적 탐색 방법이다.

 


 

하지만 동적 타이핑 언어는 이러한 방법을 사용하기 어렵다.

일단 객체의 프로퍼티나 메서드가 선언되는게 컴파일 단계가 아니라 런타임 과정이기 때문에 오프셋을 미리 알아두기가 힘들다.

 

런타임 과정에서 객체를 선언하는 코드를 딱 선언하게 될 때, 프로퍼티나 메서드의 오프셋을 알 수 있게 된다.

 

더구나 중간에 프로퍼티가 추가되거나 삭제되면 프로퍼티 순서가 처음 초기화할 때와는 달라질 수도 있고, 타입도 달라질 수도 있다.

이 때문에 동적 탐색(dynamic lookup)을 사용한다.

 

그러니까 쉽게 말해서 런타임 과정에서 프로퍼티를 찾아내야 한다.

때문에 정적 탐색보다는 런타임 과정에서 해야하는 일이 더 많고 시간도 더 필요하다.

즉, 프로퍼티에 접근하는데 비용이 발생한다.

 

다만, 보통 이런 동적 탐색의 특징 때문에 그대로 사용하지는 않고, 동적 탐색 캐시를 사용하는 듯 하다.

(자세한 사항은 아래의 글 참고)

https://docs.informatica.com/integration-cloud/cloud-data-integration/current-version/transformations/lookup-transformation/dynamic-lookup-cache.html

 

Dynamic lookup cache

 

docs.informatica.com

 

 

✅ V8 : 히든 클래스 방식

위와 같은 동적 탐색의 특징 때문에(비용이 발생) V8은 동적 탐색 대신에 히든 클래스라는 방식을 사용한다고 한다.

(프로퍼티에 접근할 때 들어가는 비용을 더 줄여보기 위해서)

#히든 클래스라는 방식을 이용해서 거의 C++ 객체의 프로퍼티에 접근하는 정도의 성능까지 보장한다고 한다.

 

이 히든 클래스 방식을 쉽게, 한 줄로 나름 정리해보면 '정적 탐색처럼 오프셋을 관리하자'가 될 것 같다.

 

const obj = {};

빈 객체를 생성하면 V8 엔진은 내용이 비어있는 히든 클래스를 만든다. (이 순간의 히든 클래스를 A라고 한다) 

그리고 이 객체에 프로퍼티를 추가해보자.

obj.age = 10;

이때, 히든 클래스는 이전 히든 클래스(= A)의 모든 프로퍼티를 상속해서 새로운 히든 클래스 "B"를 생성한다.

그리고 히든 클래스 A에는 offset 0에 "age"라는 프로퍼티를 할당한다.

이 offset 0의 의미를 쉽게 정리하면 "age라는 프로퍼티를 추가하면 참조하는 히든 클래스는 B로 전환됩니다'라는 의미가 된다고 한다.

그리고 히든 클래스 B는 히든 클래스 A를 가리키도록 설정한다.

 

프로퍼티가 추가될 때마다 이런 과정이 반복된다고 한다.

너무 어렵다면, TOAST의 글에서 친절하게 그림을 그려가며 히든 클래스를 설명해주고 있으니 그 부분을 꼭 읽어보자.

 

https://ui.toast.com/weekly-pick/ko_20210909

 

자바스크립트 성능의 비밀 (V8과 히든 클래스)

자바스크립트가 C++ 성능에 도달한 방법

ui.toast.com

 

 

 


 

 

참고자료 1 :

https://engineering.linecorp.com/ko/blog/v8-hidden-class/

 

V8의 히든 클래스 이야기

2022-LINE-engineering-site

engineering.linecorp.com

 

참고자료2 :

https://ui.toast.com/weekly-pick/ko_20210909

 

자바스크립트 성능의 비밀 (V8과 히든 클래스)

자바스크립트가 C++ 성능에 도달한 방법

ui.toast.com

 

Comments