oowgnoj, https://oowgnoj.dev/review/advanced-js-1
참고 사이트에 내용을 개인적으로 복습하기 편하도록 재구성한 글입니다.
자세한 설명은 참고 사이트를 살펴보시기 바랍니다.
1995년 자바스크립트는 유저와의 상호작용을 위해 10일만에 탄생한 언어입니다. HTML 페이지를 동적으로 만드는 것에 목적을 가지고 가벼운 인터프리터 언어로 만들어졌습니다. 구글은 구글맵스를 개발하며 당시 브라우저, 특히 javascript 엔진에 한계를 느꼈습니다. 많은 유저 인터랙션이 필요했고, 이를 커버할 수 있는 좋은 엔진이 필요했습니다.
답답함을 느낀 구글은 2009년 V8 엔진을 출시했습니다. 크롬 V8 엔진이 기존과 어떻게 달라져 획기적인 성능 향상이 있었을까요? 이번 글에서는 V8엔진을 비롯해 현대 자바스크립트 엔진이 성능을 어떻게 향상시켰는지 살펴보겠습니다.
compile 언어와 interpreter 언어의 가장 큰 차이점은 pre-processing, 컴파일의 유무입니다. 컴파일이란 프로그래밍 언어를 컴퓨터가 이해할 수 있는 기계어로 변환하는 과정입니다. 대표적으로 C, C++, JAVA 등의 프로그래밍 언어가 있습니다. 변환된 기계어는 고급 언어를 바로 인터프리팅 방식으로 실행한 것보다 빠릅니다. 아래 예제를 통해 컴파일 방식의 성능이 월등히 좋은 대표적인 경우를 살펴보겠습니다.
function sum () {
let result = 0
for (let i = 1 ; i <= 10 ; i++){
result += i;
}
return result;
}
// interpreter 결과
sum() // for loop 후에 55 반환
sum() // for loop 후에 55 반환
sum() // for loop 후에 55 반환
// compile 결과
sum() = 55
sum() = 55
sum() = 55
컴파일을 마친 기계어는 sum()
의 결과를 55
로 기억합니다. 반면 인터프리터 언어는 매번 sum()
을 실행해 for
문을 거쳐, 55
를 반환합니다.
자바스크립트는 interpreter 언어입니다. 개발자도구 콘솔에서 스크립트를 작성해 실행하는데 컴파일이 필요하지 않기 때문입니다. 하지만, 결론부터 이야기하면 자바스크립트도 컴파일 과정을 거칩니다. 다만 자바스크립트 엔진 내부에서 실행 도중 컴파일이 필요한 경우에 내부에서 컴파일 합니다. 대표적인 현대 자바스크립트 엔진인 크롬 V8의 내부를 조금 살펴보겠습니다.
자바스크립트의 성능을 비약적으로 향상시킬 수 있었던 이유는 엔진 내부에서 컴파일 과정 거치기 때문입니다. 엔진이 작동하는 원리는 우선 엔진이 실행할 JS 파일을 받은 후 파싱, AST(Abstract Syntax Tree)를 구축하는 과정을 거칩니다.
다음으로 Interpreter가 코드를 읽으며 실행합니다. 코드를 수행하는 과정에서 프로파일러가 지켜보며 최적화 할 수 있는 코드를 컴파일러에게 전달해줍니다. 주로 반복해서 실행되는 코드 블록을 컴파일(최적화)합니다. 그리고 원래 있던 코드와 최적화된 코드를 바꿔줍니다.
코드를 우선 인터프리터 방식으로 실행하고 필요할 때 컴파일 하는 방법을 JIT(Just-In-Time) 컴파일러 라고 부릅니다. 크롬의 V8 엔진을 포함해 Mozilla의 Rhino, Firefox의 SpiderMonkey도 같은 방법을 사용합니다.
결론은, 자바스크립트는 실행되는 플랫폼에 따라 인터프리팅과 컴파일이 혼합되어 사용됩니다. 이 방식은 자바스크립트의 성능을 크게 향상시켰습니다.