JavaScript Engine
포스트
취소

JavaScript Engine

js-engine-overview

컴퓨터는 우리가 작성한 JavaScript 파일을 이해하지 못합니다. 따라서 위 그림처럼 JavaScript EngineJavaScript 파일을 컴퓨터가 이해할 수 있는 형태로 변환시켜 줍니다.
JavaScript Engine종류는 다양하지만 그 중 크롬 브라우저에서 사용되는 V8 엔진을 예시로 JavaScript Engine을 살펴보겠습니다.

💻 Engine

js-engine-detail

👨‍💻 Parser

작성한 코드를 분석(lexical analysis)해 ‘토큰(token)’이라는 작은 단위로 코드를 분해하는 역할을 합니다.

👨‍💻 AST (Abstract Syntax Tree)

만들어진 토큰들을 기반으로 Parser는 추상 구문 트리(AST)를 만듭니다.
AST는 이름에서 알 수 있듯이 트리 형태를 띄고 있습니다. 또한 원래 구문의 모든 세부사항이 표현되지 않기 때문에 추상(Abstract)이라는 이름이 붙었습니다. AST이곳에서 테스트해 볼 수 있습니다.

👨‍💻 Interpreter, Compiler

🖊 Interpreter VS Compiler?

V8 엔진에서 InterpreterCompiler가 어떤 역할을 하는지 알아보기 전에 각각이 무엇인지 어떤 특성을 가지고 있는지를 먼저 살펴보겠습니다.
Interpreter는 코드를 즉석해서(on the fly) 읽고 Bytecode로 변환해 실행합니다. 따라서 초기 속도가 빠르다는 장점이 있습니다.
하지만 많은 코드를 실행시킬수록 느려질 가능성이 있습니다. 아래의 예시를 살펴보겠습니다.

1
2
3
4
5
6
7
function multiply(a, b) {
  return a * b;
}

for (let i = 0; i < 1000; i++) {
  multiply(5, 4);
}

위 코드는 multiply라는 함수를 반복문을 통해 여러번 실행시키는 코드입니다.
interpretermultiply라는 함수가 항상 같은 값을 반환하더라도 매번 실행하게 됩니다. 이는 비효율적이 작업으로, 이런 작업이 여러군데에서 발생하게 되면 성능저하로 이어지게 됩니다.

CompilerInterpreter와 반대되는 특성을 가지고 있습니다.
Compiler는 코드가 실행되기전, 사전에 모든 코드를 읽어 Machine Code로 변환합니다.
따라서 Interpreter보다 초기 속도가 느리다는 단점이 있지만, 전체 코드를 변환하는 과정에서 최적화가 되어 interpreter에서 발생하는 비효율적인 작업을 피할 수 있다는 장점이 있습니다.

위에서 서술한 특징을 정리하면 아래와 같습니다.

 InterpreterCompiler
초기 속도사전 변환 단계 없이
한줄씩 읽어 가며 변환 및 실행하므로 빠름
사전 변환 단계를 통해 모든 코드를
변환한 후 실행하므로 상대적으로 느림
성능최적화 과정이 없기 때문에 성능 저하가 발생할 수 있음사전 변환 단계에서 최적화 과정이
포함되어 성능적으로 유리함

V8엔진에서는 위에서 살펴본 두가지 방식의 장점을 합친 JIT(Just In Time) Compiler 방식으로 코드를 변환해 실행합니다.

먼저 ignition이라고 불리는 V8엔진의 interpreterAST를 읽어 bytecode로 변환하여 실행시킵니다.
이 과정에서 profiler는 코드를 모니터링하면서 최적화 될 수 있는 부분을 찾습니다.
만약 최적화 할 수 있는 부분이 있다면 interpreterturbofan이라 불리는 compiler로 코드를 보냅니다. compiler는 해당 코드를 최적화해 machine code로 변환합니다.
최적화된 코드가 상대적으로 덜 쓰이게 된다면 compiler는 다시 interpreter로 코드를 전달하게 됩니다.

이렇게 두가지 방식의 장점을 합쳐 V8엔진은 JavaScript파일을 실행시킵니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.