프로그래밍 공부하기

JS 엔진 최적화를 위한 지식1 - Hidden Class 본문

Web/[JS] Common

JS 엔진 최적화를 위한 지식1 - Hidden Class

ihl 2021. 1. 1. 19:33

JavaScript 코드의 성능에 대해 웹 서핑을 하던 중 Hidden Class라는 개념을 알게되었다. 

 

1. Dynamic Typing

  JavaScript의 특징 중 하나는 동적 타이핑 언어라는 점이다. 변수를 선언할 때 다른 언어에서 int, char 등의 타입을 함께 지정해주는 것과 달리 Javascript는 특정한 타입을 지정해주지 않는다. 또한 JavaScript는 객체의 속성을 코드 중간에 추가하거나 삭제하여 객체의 속성을 동적으로 변경할 수 있다. 이러한 특징은 코드를 작성할 때 프로그래머를 자유롭게(?) 해주지만 코드 실행 시에는 성능이 감소되는 단점이 있다.

 

  정적 타이핑 언어의 객체의 경우 객체의 속성과 속성 값의 저장 위치가 코드 실행 전에 지정이 되므로 객체의 속성에 접근할 때 미리 지정된 위치 정보를 활용하여 바로 접근할 수 있다. 그러나 동적 타이핑 언어의 경우 코드 실행 중에 객체의 속성이 변경될 수 있으므로 객체의 속성에 접근할 때 해당 속성이 어디 있는지 동적으로 찾는 과정이 필요하다. 따라서 정적 타이핑언어보다 실행 속도가 느린 것이다. 

 

2. Hidden Class

  이러한 동적 타이핑의 단점을 해결하기 위해 도입한 개념이 Hidden Class이다. Hidden Class는 정적 타이핑 언어의 Class와 유사한 특징을 가지며 JavaScript의 모든 객체는 Hidden Class를 갖고 있다. 코드를 통해 Hidden Class를 알아보자.

 

function Student(name, age){
  this.name = name;                 //2번
  this.age = age;                   //3번
}

var s1 = new Student("kim", "20");  //1번
s1["gender"] = "male";              //4번

 

위와 같은 코드에서 Hidden Class의 변화는 다음과 같다. (Hidden Class 이름은 편의상 C0, C1..로 지정한다.)

  • 1번 line
    • 아직 속성 값이 전달되지 않았으므로 s1은 빈 객체와 마찬가지이다. 
    • 객체 생성 시 Hidden Class C0가 생성되며 s1과 연결된다.
  • 2번 line
    • s1 객체에 name이라는 속성이 추가된 것과 마찬가지이다.
    • C0를 기반으로 C1이라는 Hidden Class가 생성되며 s1의 Hidden Class는 C0에서 C1으로 전환된다.
    • C1은 name 속성의 상대적 위치정보(offSet)를 저장한다.
    • C0에 name 속성을 추가하면 참조하는 Hidden Class가 C1로 전환된다는 정보가 C0에 추가된다.
  • 3번 line
    • s1 객체에 age라는 속성이 추가된 것과 마찬가지이다.
    • C1을 기반으로 C2라는 Hidden Class가 생성되며 s1의 Hidden Class는 C1에서 C2로 전환된다.
    • C2는 age 속성의 상대적 위치정보(offset )를 저장한다.
    • C1에 age 속성을 추가하면 참조하는 Hidden Class가 C2로 전환된다는 정보가 C1에 추가된다.
  • 4번 line
    • s1 객체에 gender라는 속성이 추가되었다.
    • C2를 기반으로 C3라는 Hidden Class가 생성되며 s1의 Hidden Class는 C2에서 C3로 전환된다.
    • C3는 gender 속성의 상대적 위치정보(offset)를 저장한다.
    • C2에 gender 속성을 추가하면 참조하는 Hidden Class가 C3로 전환된다는 정보가 C2에 추가된다.

 

생성된 히든 클래스

  코드를 모두 돌았을 때 생성된 Hidden Class는 위의 그림과 같다. 객체가 속성에 접근할 때 해당 객체에 연결된 Hidden Class의 offset 정보를 사용하여 정적 타이핑 언어의 클래스처럼 속성에 바로 접근가능하게 된다. 또한 Hidden Class는 재사용이 가능하므로 다른 Student 객체를 생성 후 gender 속성을 추가하면 이미 생성된 Hidden Class C3 재사용한다.

 

3. 코드 최적화

  Hidden Class 지식을 코드에 어떻게 적용해야할까? 다음과 같은 코드를 살펴보자.

function Student(name, age){
  this.name = name;                 
  this.age = age;                   
}

var s1 = new Student("kim", "20");  
s1.gender = "male";
s1.nation = "Korea";

var s2 = new Student("Lee", "21");
s2.nation = "US";
s2.gender = "male";

  s1과 s2는 속성의 종류는 같지만 속성을 추가한 순서가 다르다. 객체에서 속성의 상대적 위치인 offset은 속성이 추가된 순서에 영향을 받으므로 두 객체는 서로 다른 Hidden Class를 갖게된다. s1에서 만든 Hidden Class를 재사용할 수 없어 새롭게 Hidden Class를 만들어야하는 것이다. 이는 코드 성능에 영향을 준다. 따라서 Hidden Class라는 지식이 있는 프로그래머는 객체에 속성을 항상 같은 순서로 초기화해야한다.

 

 

 


참고 사이트:

 

자바스크립트는 어떻게 작동하는가: V8 엔진의 내부 + 최적화된 코드를 작성을 위한 다섯 가지 팁

How JavaScript works: inside the V8 engine + 5 tips on how to write optimized code

engineering.huiseoul.com

 

 

V8의 히든 클래스 이야기 - LINE ENGINEERING

자바스크립트가 되어 그 기분을 헤아릴 수 있다면 안녕하세요? LINE Fukuoka의 프론트엔드 엔지니어 Yonehara입니다. 저는 프론트엔드 개발자로서 아직 웹 브라우저나 자바스크립트의 기분을 헤아려

engineering.linecorp.com

'Web > [JS] Common' 카테고리의 다른 글

?. 연산자(Optional Chaining)  (0) 2021.01.01
??(null 병합 연산자)  (0) 2021.01.01
논리연산자 AND, OR의 결과값  (0) 2020.12.31
내장고차함수: filter, map, reduce  (0) 2020.12.22
호이스팅(Hoisting)  (0) 2020.12.17
Comments