컴파일러와 동적언어, Compiler and dynamic language

정적언어(컴파일) vs. 동적언어(인터프리터)

정적언어동적언어

해석과정

코딩 → 빌드 → 기계어

코딩 → 빌드로 인한 중간상태

특징

전체 프로그램의 컴파일 과정을 거친다.

프로그램을 읽을 때 필요한 부분만 중간중간 기계어로 변환해서 읽는다.

대표언어

C, C++, Go

Java, Python, C#, Javascript

돈까스에 비유

돈까스를 처음부터 모두 잘라서 찍어먹는 것

돈까스를 한조각씩 잘라서 먹는 것

속도

한꺼번에 컴파일된 내용을 읽기만 하면 되니까 빠르다

그때그때 해석해야하기에 느리다

컴파일 언어

  • 프로그래머가 작성한 코드가 → 컴파일러를 통해서 빌드가 되고 → 기계어로 변환된 실행파일이 생성된다.

  • 컴퓨터는 바로 이 실행파일을 읽어 프로그램을 실행한다.

동적언어

  • 동적 언어는 컴파일 과정이 필요 없음

  • 프로그래머가 작성한 코드가 → 빌드를 거치거나 안거쳐서 (언어마다 상이) → 중간언어의 형태로 만든다.

  • 컴퓨터가 프로그램을 실행하면서 바로바로 이 중간언어를 → 기계어로 변환하여 프로그램을 실행한다.

컴파일 언어가 속도가 빠른데 왜 동적언어가 생겨났을까

  • 컴파일 언어에는 각 플랫폼 별로 다른 변환이 필요하다는 큰 문제점이 있었다.

  • 예를 들어보자.

    • 윈도우즈에서의 스타크래프트와 MAC에서의 스타크래프트 실행파일은 엄연히 다르다.

    • 컴파일 언어로 스타크래프트를 만든다면, 윈도우용 스타크래프트를 작업하고, MAC용 스타크래프트를 작업하는 등 같은 작업을 플랫폼 별로 반복해야했을 것이다.

왜 컴파일 언어는 플랫폼 별로 다른 변환이 필요할까

  • 우선 첫번째로, 옛날에는 CPU를 만드는 회사별로 명령어를 변환하는 OPCODE 체계가 달랐다.

    • 가령 ADD 3, 4 를 수행한다고 했을 때,

      • 인텔은 ADD를 0001로,

      • IBM은 ADD를 0100으로,

      • AMD은 ADD를 0111로 변환을 하는 코드체계를 가지고 있었다.

  • 다음으로는 한 회사의 CPU 칩셋 내부에서도 OPCODE 의 체계가 업데이터 되는 경우가 있었다.

    • 인텔 CPU의 경우 아래와 같은 업데이트 역사를 가지고 있다.

      • 8086 → 80286 → 80386 → 80486 → 펜티엄 - 펜티엄MMX → I3 → I5 → I7

    • 문제는 업데이트가 되는 과정에서 이전에 없던 새로운 명령어를 지원하게 되면서 OPCODE 도 추가되는 것이다.

  • OS 역시 문제였다.

    • WINDOWS, MAC, Linux, Solais, O/S 2

    • 각 OS 마다 실행파일을 만드는 방식도, 실행파일을 실행하는 방식도 모두 달랐다.

결국, 컴파일 과정에서 CPU와 OS를 고려하여 빌드를 진행해야했던 것이다.

이를 해결하기 위해 등장한 것이 동적언어이다.

  • Java 의 예시로 보면

    • 코딩을 하고 → 컴파일러를 통해 빌드가 되어 → .jar 파일로 변환이 되면 → CPU나 OS 에 상관없이 어디에서나 실행이 가능하다.

  • 비록 기존 컴파일 언어보다는 속도가 느려지기는 했지만, 언어의 완성도가 더 높아졌고, 가장 결정적으로는 플랫폼으로 인한 제약사항이 없어지게 되었다.

  • 게다가 현재 하드웨어의 성능이 점점 발전하고 있는 상황에서는 컴파일 언어인 C, C++과 동적 언어인 Java 의 속도차이가 거의 없거나 오히려 동적언어가 더 빠른 경우도 종종 보고되고 있다.

Last updated