V8은 독일의 Google development center 에서 만들어진 자바스크립트 엔진 입니다. 이 엔진은 C++로 만들어진 Open source 이며, 클라이언트 측 (Chrome)과 서버 측 (node.js)의 JavaScript 애플리케이션 모두에 사용됩니다.
V8은 웹 브라우저 내에서 JavaScript 실행 성능을 높이기 위해 처음 개발되었습니다. V8은 속도를 높이기 위해 인터프리터 대신 JavaScript 코드를 보다 효율적인 기계어로 변환합니다. SpiderMonkey 나 Rhino (Mozilla)와 같은 많은 최신 자바 스크립트 엔진과 같이 JIT (Just-In-Time) 컴파일러 를 구현하여 실행 시 JavaScript 코드를 기계어로 컴파일합니다 . V8과의 주요 차이점은 바이트 코드 또는 중간 코드를 생성하지 않는다는 점입니다.
이 글의 목적은 클라이언트 측 또는 서버 측 애플리케이션 모두에 최적화 된 코드를 생성하기 위한 V8의 작동 방식 을 보여주고 이해하기 위함 입니다. "JavaScript 성능에 관심을 가져야 할까요?"라고 묻는다면, Daniel Clifford (V8 팀 기술 책임자 겸 관리자)의 말을 인용하여 대답 할 것입니다. "현재의 애플리케이션을 더 빨리 실행할 수있는 것은 아닙니다. 과거에는 할 수 없었던 일들을 가능하게 합니다."
JavaScript는 프로토 타입 기반 언어입니다. 복제 프로세스를 사용하기 때문에 클래스와 객체가 생성 되지 않습니다. JavaScript는 또한 동적으로 type이 지정됩니다. type 및 type 정보는 명시적이지 않으며 property 는 직접적으로 객체에 추가 및 삭제 할 수 있습니다. type 및 property 에 효과적으로 액세스하는 것이 V8의 첫 번째 큰 도전 과제입니다. 객체 property 를 저장하기 위해 사전과 같은 데이터 구조를 사용하고 (대부분의 자바 스크립트 엔진과 마찬가지로) property 위치를 확인하기 위해 동적으로 검색을 수행하는 대신 V8은 runtime 에 hidden class를 생성 하여 type 시스템의 내부 표현을 갖고, 속성 액세스 시간을 향상시키고 있습니다.
예를 들어, Point
함수와 두 Point
객체를 생성을 보겠습니다 .
만약 위 사진과 같다면, 이 경우 p
와 q
는 V8에 의해 생성 된 같은 hidden class에 속합니다. 이는 hidden class 를 사용하는 또 다른 장점입니다. V8에서는 속성이 동일한 객체를 그룹화 할 수 있습니다. 다음 p
과 q
는 최적화 된 코드를 같이 사용합니다.
이제, 선언 직후의 q
객체에 z
속성 을 추가하려 한다고 가정 해 봅시다
V8은 이 시나리오를 어떻게 다룰까요? 사실 V8은 생성자 함수가 속성을 선언 하고 hidden class 의 변경 사항을 추적 할 때마다 새로운 hidden class를 만듭니다. 왜냐하면, 두 개의 객체가 생성되고( p
그리고 q
), 생성 후 두 번째 객체 ( q
)에 멤버가 추가 되면, V8은 최근에 생성된 hidden class를 추적하여(첫 객체 p
) 새 멤버를 위한 새 hidden class를(객체 q
) 만듭니다.
새로운 hidden class가 생성 될 때마다 이전의 hidden class 는 자기 대신 사용되어야하는 hidden class로 업데이트됩니다.
V8은 각 속성에 대해 새로운 hidden class 를 생성하기 때문에 hidden class 생성을 최소한으로 유지해야 합니다. 이렇게 하려면, 객체를 만든 후에 속성을 추가하지 말고 같은 순서로 객체 멤버를 항상 초기화 해야합니다 (다른 hidden class 트리를 만들지 않기 위해).
숫자와 JavaScript 객체를 효율적으로 표현하기 위해 V8은 둘 다 32 비트 값으로 나타냅니다 . 1비트는 Object(flag = 1) 인지 integer(flag = 0, SMall Integer 또는 SMI라고 불리는) 인지를 구별하기 위해 사용됩니다. 이이 구별 때문에 32비트 중 31비트를 값을 표현하는데 사용합니다. 그런 다음 integer 값이 31 비트보다 큰 경우 V8은 숫자를 감싸서 double 로 바꾸고 새 객체를 만들어 내부에 숫자를 넣습니다.
코드 최적화 : 자바 스크립트 객체에 값 비싼 boxing 작업을 피하기 위해 가능한 한 31 비트의 부호 있는 숫자를 사용하십시오.
V8은 배열을 처리하는 두 가지 다른 방법을 사용합니다.
코드 최적화 : V8이 배열을 처리하기 위해 "빠른 요소"를 사용하는지 확인하십시오. 즉, 키가 증가 하지 않는 경우 희소 배열을 피하십시오. 또한 큰 배열을 미리 할당하지 않도록 하십시오. 당신이 필요할 때마다 크기를 증가 시키는게 낫습니다. 마지막으로 배열의 요소를 삭제하지 마십시오.
V8에는 두 개의 컴파일러가 있습니다!
코드 최적화 : V8은 최적화 해제 를 지원합니다 . 최적화 컴파일러는 인라인 캐시에서 다양한 유형에 대한 최적화된 가정을 합니다. 이러한 가정이 유효하지 않은 경우 최적화가 해제됩니다. 예를 들어 생성 된 hidden class 가 예상 한 클래스가 아닌 경우 V8은 최적화 된 코드를 버리고 Full Compiler로 돌아와 인라인 캐시에서 다시 type을 가져옵니다. 이 프로세스는 느리고 최적화 된 후에는 함수를 변경하려 시도하면 안됩니다.
번역 감사합니다 !