본문 바로가기 메뉴 바로가기

티스토리 뷰

동적 타이핑이 가지는 코드 구현의 유연성은 javascript의 특장점 중 하나라고 볼 수 있다. 따라서 이를 사용하지 말자는 것이 아니다. 단, 이에 관한 최적화 관점을 인지하고 불필요한 동적 타이핑 남발을 자제하고 성능을 더 끌어올리자는데 이번 포스트의 의미가 있다.

 

🚩 사전 정보

 

객체 메모리 저장 : 메모리 오프셋

0⬛⬛ 1⬜⬜⬜2⬛⬛⬛

C++ 등의 언어에서는 객페의 프로퍼티에 접근할 때 구조체의 기준 메모리 주소부터 상대적인 값인 오프셋이 있다. 각각의 오프셋마다 차지하는 공간은 들어올 데이터 타입(숫자형은 8byte 등)을 통해 결정한다.

  • 정적 타이핑 언어(C++, Java ...)
    • 컴파일 이전에 객체 레이아웃이 고정되기 때문에 이때 고정된 오프셋으로 프로퍼티에 바로 접근 가능하다.
  • Javascript는 동적 타이핑 언어다
    • 동적 타이핑 언어로 구현되어 프로퍼티의 데이터 타입이나 순서, 갯수가 언제 어떻게 바뀔지 모른다. 즉, 선언시 오프셋 값은 참조할 수 없게 된다.
    • 프로퍼티 값을 읽을 때마다 프로퍼티를 찾아내야 하는 동적 탐색(dynamic lookup)이 필요하다.
    • ➕ js 인터프리터는 메모리에 객체를 저장하는데 해쉬 테이블 형식을 사용 → 접근하는데 느리다.

→ 동적 탐색을 회피하고자 V8엔진은 히든 클래스를 사용해 객체의 구조(오프셋 값)을 저장한다.

 

🚩 히든 클래스(shape)

객체의 구조(프로퍼티의 오프셋)와 히든클래스 전환에 대한 정보를 담고 있다. 자바스크립트의 '클래스' 개념과의 혼란을 막기 위해 shape라고도 불린다.
객체 프로퍼티의 수, 순서, 데이터타입이 변할 때 마다 새로운 히든 클래스를 생성한다.
function Student(name, age, grade) {
    this.name = name;   //2
    this.age = age;     //3
		this.grade = grade; //4
}
var Jim = new Student("jim", 19, 'A'); //1
var Mary = new Student("Mary", 25, 'c'); //5
var Karin = new Student("Karin", 25, ['B','C']); //6

히든 클래스 변경 개발자도구에서 확인하기

  1. 위의 코드를 콘솔 창에 입력
  2. Memory 에서 스냅샷 찍기
  3. Memory에서 Student 검색
  4. Map에 지정된 식별값이 히든 클래스의 ID

콘솔창에 찍힌 맵 식별자

 

추가로 Karin과 같이 grade 프로퍼티에 배열을 넣어준 hey를 살펴보자. 이번엔 Karin의 grade프로퍼티를 위한 히든클래스 맵을 재사용한 것을 볼 수 있다.

이미지 설명
1. Student 객체 3개가 모두 같은 히든 클래스를 가지고 있다.
2. grade 프로퍼티에 연결된 히든클래스 ID : 스트링 값으로 동일하게 넣어준 Jim 과 Mary의 ID는 같지만, 배열타입을 넣어준 Karin은 ID가 달라진 것을 볼 수 있다.
3. 추가로 Karin과 같이 grade 프로퍼티에 배열을 넣어준 hey를 살펴보자. 이번엔 Karin의 grade프로퍼티를 위한 히든클래스 맵을 재사용한 것을 볼 수 있다.

 

히든 클래스의 특징

  • 객체는 반드시 하나의 히든 클래스를 참조한다.
  • 히든 클래스는 각 프로퍼티에 대한 메모리 오프셋과 이전 히든클래스로부터의 전환 정보를 가지고 있다.
  • 기존 프로퍼티에 대한 추가, 삭제, 데이터타입의 변경 등 동적 타이핑이 일어날 때 신규 히든 클래스가 생성된다. 이 때 신규 히든 클래스는 기존 프로퍼티에 대한 정보를 가지고 오며 변경된 프로퍼티의 오프셋을 생성한다.
  •  

🚩 최적화를 위해서

동적 타이핑이 가지는 코드 구현의 유연성은 javascript의 특장점 중 하나라고 볼 수 있다. 따라서 이를 사용하지 말자는 것이 아니다. 단, 이에 관한 최적화 관점을 인지하고 불필요한 동적 타이핑 남발을 자제하고 성능을 더 끌어올리자는데 이번 포스트의 의미가 있다.

👉 객체를 다룰 때 프로퍼티 순서를 동일하게 처리 하자 (불필요한 히든 클래스 생성 방지)

👉 객체를 생성할 때 프로퍼티 초기화도 같이하자

👉 불필요하게 객체의 프로퍼티 데이터타입 및 순서, 갯수를 가능한 변경하지 말자

 

참고 링크

Franziska Hinkelmann: JavaScript engines - how do they even? | JSConf EU

V8의 히든 클래스 이야기 - By Masami Yonehara | 2018.06.14 

 

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

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

engineering.linecorp.com

 

댓글