자바스크립트 엔진과 작동원리(Javascripts engine and principal)

1
post-thumbnail

Javascripts Engines

자바스크립트의 엔진은 무엇인지 알아보고 그 작동 원리에 대해 알아보자.

자바 스크립트 엔진에 대해 거론하기 앞서, 브라우저는 우리가 작성한 Javascripts의 코드를 어떻게 해석하고 브라우저에 보여줄까?

여러분도 알다 싶이 컴퓨터는 기계어(0과 1로 된 숫자의 조합의 값)으로만 이해하도록 되어있다. 우리의 자바스크립트 코드를 컴퓨터에게 바로 보여준다면 과연 그 결과물을 제대로 출력되고 컴퓨터가 인지 할 수 있을까?

이에 대한 징검다리 역활을 해주는게 자바스크립트 엔진이라고 할 수 있다.

자바 스크립트 언어로 작성한 파일을 컴퓨터가 읽을 수 있는 기계어로 번역하여 도와주는 번역기 같은 역활을 하는게 이 자바스크립트 엔진이라고 보면된다. 다른 비유로는 징검다리 역활이라고 할 수 있다. js file을 컴퓨터(machine)이 이해하고 그것을 display에 나타내도록 해주는 것이라고 할 수 있다.

자바스크립트 엔진은 그러면 몇개일까?

종류는 여러가지가 있는데, Google Chrome의 V8, Mozilla Firefox의 SpiderMonkey 등이 있으며,

주로 우리가 쓰는 것은 V8인데 크롬과 node.js 에서 쓰인다. 참고로 이 엔진은 저 수준언어인 c++로 만들어졌다. 구글이 쓰기 만들었고 구글 브라우저를 다들 많이 쓰기 떄문이 아닐까 생각한다.

Quiz?

누가 처음 자바스크립트 엔진은 만들었을까?

정답은 너도 알다 싶이 브렌던아이크(Brendan Eich) 아저씨가 제일 처음 만든 엔진이다.

Netscape에서 일할 때 만든 spider moneky로서 현재 파이어폭스에는 아직도 이것을 사용하고 있다.

자바스크립트 엔진의 구조

자바스크립트 엔진(이하 자바스크립트 엔진은 V8 엔진을 의미)은 위 사진처럼 구성되어 있다.

  • Parser : Lexical Analysis(코드의 의미를 이해하기 위해 token이라는 작은 단위들로 코드를 쪼개는 일)를 진행한다. 코드를 의미하기 위해 쪼개서 token이 형성되고 이 token들이 다시 AST에 의해 형성된다.

  • AST : Abstract Syntax Tree의 약자로, parser에서 분해된 token들을 기반으로 나무 구조

    를 만든다.(ex. DOM Tree, CSSOM Tree가 구성되는 것과 비슷한 개념이다.)

    • AST Explorer : 코드가 어떻게 나무 구조로 변경되는지를 시각적으로 볼 수 있는 사이트.
  • AST에서 생성된 나무 구조는 인터프리터와 컴파일러를 거쳐서 컴퓨터가 이해할 수 있는 BytecodeOptimized Code로 변환되어 컴퓨터가 이해하게끔 해주는 것이 전체의 엔진의 작동원리라 할 수 있다.

자바스크립트 엔진의 구조와 구성 원리를 이해하면, 반대로 코드를 작성할 때 어떻게 Optimized Code, 효율적으로 최적화된 코드를 작성할 수 있는지를 알 수 있다.

간단한게 쉽게 하기 위한 js엔진을 만들어 보면서 이해해보자~

아래 처럼 js engine에 우리가 코드를 작성하면 js엔진은 문자열을 정의하고 코드를 분해하는 과정을 거친다.

오른쪽에 보이는 것처럼 코드를 잘개 쪼갠다.

ECMAScripts engines

우리는 JS engine이라고 부르지 않고 왜 ECMA SCripts engines이라고 부를까?

이에 대해 자세히 알아보자~

앞서 우리는 누구나 js engine을 만들 수 있다고 했다. 하지만, 문제는 모두가 자신의 js 엔진을 만들면 어떤 문제가발생할까? 완전 말 그대로 chaos일 것이다. 그래서 ECMA scripts라는 표준규범이 만들어진 것이다.

ECMA international 은 정보 통신에 대한 표준을 제정하는 비영리 표준화 기구 이고, EMCAScripts는 Ecma인터네셔널에 의해 제정된 ECMA-262 기술규격에 의해 정의된 범용 스크립트 언어라 할 수 있다.

이러한 ECMAScripts의 기반을 바탕으로 만들어진 것이 javascripts이라 할 수 있다.

그리고 이러한 규격에 맞춰 엔진 개발자가 만들기 때문에 출처의 문서에서도 ECMAScripts Engine이라고 불리는 것이다.

출처: https://en.wikipedia.org/wiki/List_of_ECMAScript_engines

Interpreters vs Complier

JavaScript는 각 브라우저의 엔진에 따라 다양한 방식으로 실행 전에 컴파일이 된다.

그래서 흔히 우리는 JavaScript는 JavaScript를 인터프리터 언어라고 하지만 원리를 알고 나면사실은 컴파일 언어라고도 할 수 있다.

프로그램 언어를 해석하고 실행시키는 대표적인 방법으로는 complie과 interpret 방식이 있다.

이 두가지 방식에 대해 알아보자~

프로그래밍 언어(고수준 언어)를 기계가 이해할 수 있는 저차원 언어로 변환하는 방식은 크게 2가지 방식이 있다. ① 인터프리터를 이용한 변환과 ② 컴파일러를 이용한 변환이다.

인터프리터 : 코드를 한 줄 한 줄 읽어내려가며 한 줄씩 Bytecode로 변환한다. 런타임(Runtime) 이후에 Row 단위로 해석(Interpret) 하며 프로그램을 구동시키는 방식이다.

컴파일러 : 한 줄 한 줄 번역하지 않고 파일 전체를 읽은 뒤, 코드의 의미를 해석하고 파일 전체를 기계어로 컴파일해서 변환한다. 프로그랭밍 언어를 Runtime 이전에 기계어로 해석하는 작업방식이라고 할 수 있다.

대표적인 언어로 C/C++ 가 있다.

인터프리터의 경우 자바스크립트 파일을 입력받으면 한 줄 한 줄 해석하면서 중간 단계의 Bytecode로 변환한다. 반면 컴파일러는 자바스크립트 코드를 입력받으면 파일 전체를 읽은 뒤, 이를 컴파일하여 기계어로 변환한다. 그리고 이 기계어(Machine Code)는 CPU로 입력되어 코드가 실행된다.

인터프리터(interpreter)

프로그래밍 언어를 기계어로 바로 바꾸지않고 중간 단계를 거친 뒤, 런타임에 즉시 해석하기 때문에 바로 컴팩트한 패키지 형태로 Binary 파일을 뽑아낼 수 있는 Compile 방식에 비해 낮은 퍼포먼스를 보이게 된다.

  • 장점 : 런타임에 직접 코드를 구동시키는 특징이 있기 때문에 오류를 내도 그 전까지는 작동이 되기 때문에 실제 실행시간은 느리지만, 대신 런타임에 실시간 Debugging 및 코드 수정이 용이하다.또한 메모리를 별도로 할당받아 수행되지 않으며, 필요할 때 할당하여 사용하는 장점이 있다.
  • 단점 : 자바스크립트 코드가 복잡해질수록 점점 속도가 느려진다. 반복을 여러번 하는 기능의 함수가 있다고 치고 이 함수를 여러번 돌리는 코드가 작성이 되어있다고 해보자. 이 함수의 경우는 100번의 반복문이 돌아간다.이 함수를 3번 사용한다고 하면 이 경우 3백번을 반복해서 코드변환 과정을 계속 거쳐야 하기 때문에 실행 속도가 느려질 수 있다. 지금은 예시가 적지만 로직이 정말 복잡하며 1억이상 돌려서 알아봐야하는 과정의 경우는 확실히 구동속도에서 차이가 날 수 있다.

컴파일러(compiler)

  • 장점 : 컴파일러는 작업을 단순화시킨다. 자바스크립트 작동원리에서 보왔던 것처럼 코드를 최적화하는 과정(optimization)을 거친다. 복잡한 로직의 함수를 여러번 하는 과정을 실행시킨다고 했을 때, 한번 기계어로 번역 후 저장하기 때문에 인터프리턴의 방식보다 상대적으로 실행속도가 빠르다고 할 수 있다. 퍼포머스에는 확실히 인터프리터 방식보다는 좋다고 할 수 있다.

  • 단점 : 컴파일러는 한번에 번역을 하고 실행을 하기 때문에 프로그래머가 코딩을 하다가 오류를 작성 했을 때 전부 작성을 하고 실행파일을 만들어서 실행을 해봐야 알 수 있다.

결론

크롬 v8엔진 구조를 살펴 본것 처럼 기본적으로는 한줄 씩 쪼개 bycode로 반환하는 인터프리터 방식을 사용하지만 자바스크립트 엔진 내부에서는 프로파일러가 지켜보고 이를 컴파일언어로 먼저 번역하겨 코드를 최적화하는 과정을 거친다. 그렇기 때문에 자바스크립트는 코드를 인터프리티 방식으로 실행하고 실행중 컴파일 필요할 때 내부에서 컴파일을 하기 때문에 기본적으로는 인터프리터 언어이지만 컴파일 언어라고도 할 수 있다. 이러한 방식을 JIT 컴파일 방식이라고 하며 이는 두가지를 혼합한 방식이다.

참고로 그 최적화의 방법 중 하나로 히든 클래스와 인라인 캐싱이 크롬 엔진에 있다.

참고자료:

https://fhinkel.rocks/2017/08/16/Understanding-V8-s-Bytecode/

Udemy: advanced-javascript-concepts

profile
문과생 개발자되다

0개의 댓글