컴파일러와 인터프리터의 차이

Hansu Kim·2021년 9월 15일
0

개발 Must-know

목록 보기
1/9

기본적인 정의

두 방식은 소스 코드를 어느 시점에 해석하느냐에 따라 구분된다.

  • 컴파일러는 런타임 이전에 기계어로 프로그래밍 언어를 변환하여 실행파일 생성

  • 인터프리터는 런타임에 소스코드를 Row 단위로 즉시 해석

    → 컴파일러가 인터프리터보다 실행 속도 빠름

컴파일 방식은 런타임 이전에 코드를 번역하여 기계어로 전환시키기에, OS 및 빌드환경에 종속적이다.

인터프리터 방식은 런타임에 직접 코드를 구동시키기 때문에 실행시간이 느리지만 런타임에 실시간 디버깅 및 코드 수정이 가능하다.

다만 인터프리터 방식은 메모리를 별도로 할당받아 수행하지 않고 필요할 때 할당하여 사용하기에, 수행 시점에 맞추어 Duck Typing이 가능하나 정적 분석이 되지 않는다.

Duck Typing

  • 사람이 오리처럼 행동하면 오리로 봐도 무방하다라는게 덕 타이핑(Duck Typing)이다.

  • 타입을 미리 정하는게 아니라 실행이 되었을 때 해당 Method들을 확인하여 타입을 정한다.

  • 장점

    • 타입에 대해 매우 자유롭다.
    • 런타임 데이터를 기반으로 한 기능과 자료형을 창출하는 것
  • 단점

    • 런타임 자료형 오류가 발생할 수 있다 런타임에서, 값은 예상치 못한 유형이 있을 수 있고, 그 자료형에 대한 무의미한 작업이 적용된다.
    • 이런 오류가 프로그래밍 실수 구문에서 오랜 시간 후에 발생할 수 있다
    • 데이터의 잘못된 자료형의 장소로 전달되는 구문은 작성하지 않아야 한다. 이것은 버그를 찾기 어려울 수도 있다.

    정적 분석

    정적 분석이란 프로그램을 실행 시키지 않고 코드 분석을 수행

중요한 것은 언어의 속성이 아닌 구현체의 디자인

어떤 언어 자체를 인터프리터 언어/컴파일 언어로 구분하는 것은 잘못된 접근이다. 이 두 방식은 언어 구현에 있어서의 접근법이며, 기존에 존재하는 언어라도 새 구현체를 만들어서 그 작동 방식을 바꿀 수 있다. 최근 개발되는 언어들과 혹은 아주 오래되었지만 계속해서 발전해나가는 언어들은 표준 구현에서 두 가지 방식에서 장점만을 취하거나, 혹은 필요에 따라서는 두 가지 방식 모두를 포함하는 형태로 개발되고 있다.

어떤 언어로 개발되었든, CPU가 실행할 수 있는 명령은 모두 네이티브 코드인 CPU 인스트럭션 뿐이다. 따라서 어셈블리어로 된 코드가 아닌 이상 대부분의 언어는 번역이 필요하고, 소스코드부터 출발하여 프로그램이 실행되는 과정에서 가장 비용이 많이 드는 구간은 소스코드를 해석하는 과정이다.

따라서 어떤 언어가 프로덕션 레벨에서도 고전적 의미의 인터프리터처럼 매번 소스코드의 매 라인을 해석해서 실행해야 한다면 이 해석작업 때문에 전체 프로그램의 퍼포먼스에서 크게 손해를 보게된다. 이런 문제를 극복하기 위해 파이썬과 자바는 소스코드를 바이트로 코드로 컴파일한다음, 이 바이트코드를 해석기가 돌려주는 방식으로 실행한다. 이 때 말하는 바이트코드는 해석기가 사용하는 명령어 세트로 처리된 코드로 가상 머신을 위한 어셈블리 코드 정도로 이해하면 된다.

예를 들어, Java의 경우, .java로 된 파일을 javac (java compiler)가 바이트 코드로 변환(.class)해주고, 바이트코드로 구성된 코드를 JVM에서 각 운영체제에 맞게 기계어로 번역한다.

(JVM/JRE 내에 탑재된 JIT를 활용하여 런타임에 기계어 코드를 직접 생성하여 구동)

참고
https://cbw1030.tistory.com/276
https://soooprmx.com/파이썬은-인터프리터언어입니까/
https://jaeseongdev.github.io/development/2021/03/08/JAVA는인터프리터방식과컴파일방식이혼합된언어이다/
https://medium.com/@ahn428/java-jit-컴파일러-c7d068e29f45

0개의 댓글