티스토리 뷰

컴파일러(Compiler), 인터프리터(Interpreter)

파이썬 학습 도중, CS 공부하면서 대충 알고 넘겼던 컴파일러와 인터프리터에 대한 정리가 필요하겠다 싶어서 블로그 포스팅을 하기로 결정했다. 내 개발 블로그의 첫번째 주제는 컴파일러와 인터프리터에 대한 이해이다 ! 먼저, 기본적인 프로그래밍 언어에 관하여 설명을 하고 컴파일러와 인터프리터에 대한 비교를 진행하겠다.

 

컴퓨터는 어떻게 프로그래밍 언어를 이해할까?

인간이 언어를 작성하면 컴퓨터가 이해하도록 변환하는 과정이 필요해요.

 

인류의 위대한 과학적인 업적인 컴퓨터의 발명을 우리는 당연하게 생각하며 사용해왔다. 현재에 이르러 많은 것을 가능하게 한 컴퓨터가 돌아가는 간단한 원리를 살펴보고자 한다.

컴퓨터 본체라는 하드웨어가 있는 상태에서 뛰어난 개발자들이 프로그래밍 언어로 작성하여 개발한 운영체제, 어플리케이션을 활용하여 컴퓨터를 작동시킨다. 쉽게 말하여, 프로그래밍 언어는 컴퓨터와 의사 소통하기 위한 표현법 이다. 우리가 흔히 하는 SNS, 웹 사이트, 게임 모든 것은 프로그래밍 언어로 작성된다. 프로그래밍 언어는 흔히 저급 언어(Low-Level language)고급 언어(High-Level language) 로 나뉜다.

고급 언어(High-Level language)는 코딩 공부를 처음하면서 배웠던 C language, 혹은 Java, 지금 학습 중인 Python 등 인간에게 그나마 친숙한 언어로 작성되어 있는 언어 를 뜻한다. 예를 들어, 표현 방법에 있어서 C언어의 출력은 printf("Hello world!"); Java의 경우 System.out.print("Hello World!"); Python의 경우 print("Hello World!")이다. print나 system.out.print와 같은 문구를 보면 "아, 현재 작성된 문법은 출력을 뜻하는 것이구나."라고 유추가 가능하다. 인간에게 친숙한 언어로 작성되어 있기 때문이다.

저급 언어(Low-Level language)는 컴퓨터가 이해하기 쉽게 작성된 프로그래밍 언어이다. 흔히, 어셈블리어(Assembly language)와 기계어(machine language)를 뜻한다. 어셈블리어는 add, lw와 같이 문법이 구성되어 있는 경우가 많은데 인간이 알아볼 수는 있지만 공부하지 않았다면 보고 뜻을 유추하기 힘든 경우가 많아진다. 기계어는 말 그대로 0과 1의 이진수로 이루어진 것이다. 컴퓨터는 결국 전자기기라서 전기적인 신호를 회로에 보내줘야 작동하니까 기계어까지의 변환 과정이 필요한 것이다.

인간이 작성한 내용을 컴퓨터가 이해하여 작동하려면, 일련의 과정을 거친다. 이 과정을 컴파일 과정이라고 한다. 소스 코드인 고급 언어를 컴파일러를 통하여 목적 코드인 어셈블리어로 변환한다. 그 다음에 소스 코드인 어셈블리어를 어셈블러를 통하여 목적 코드인 기계어로 변환한다.

 

컴파일 과정은 왜 반드시 필요할까?

좁은 의미로 보면 인간이 작성한 언어를 컴퓨터가 이해하도록 변환해주는 것이지만, 조금 더 상세하게 보겠다. 컴퓨터 구조 전공 수업에서 들었던 내용이기도 한데, 컴퓨터를 이용하는 수많은 사용자들의 컴퓨터는 모두 동일한 것이 아니다. 쉽게 말하자면, 프로그래밍 언어의 고급 언어는 약속된 문법을 사용하기 때문에 윈도우인 내 컴퓨터로 python을 작성하든 맥북을 사용하는 옆집 철수의 컴퓨터로 python을 작성하든 똑같은 문법을 사용하여 똑같은 것을 작성할 것이다.

그러나, 운영체제가 다르면 ISA(Instruction Set Architecture)도 다르고 컴퓨터가 작동하는 원리에 차이가 있을 수 밖에 없다. (ISA에 관련된 내용은 깊게 다뤄야해서 추후에 따로 포스팅 하겠다.) 같은 윈도우라도 window 7, 혹은 window 10과 같이 사용자의 컴퓨터들은 차이점이 반드시 존재한다. 컴퓨터 내부의 CPU, RAM 등 모든 부품에도 차이가 있기 때문에 사용자의 환경에 맞는 적절한 전기 신호를 보내야 하는데 인간이 작성한 고급 언어만 보고는 그런 작업을 할 수 없다. 컴파일 과정을 통해 각자의 환경에 맞는 어셈블리어로 변환하고 기계어로 변환해야 하는 것이다.

 

컴파일러가 뭔지 느낌은 오는데… 그러면 인터프리터는?

두 친구는 비슷하면서도 확연히 다른 친구에요.
하지만, 시간이 지날수록 그 경계가 모호해지고 있어요. 구분하는 것에 중점을 두지는 마세요 !

 

고급 언어를 컴퓨터가 이해할 수 있도록 변환하는 과정은 변환하는 방식에 따라 프로그램을 컴파일하는 컴파일러, 프로그램을 인터프리터에 통과시키는 인터프리터로 나눈다.

컴파일러와 인터프리터가 하는 역할은 원래의 코드, 즉, 원시 코드, 소스 코드가 있는데 컴퓨터가 이해할 수 있게 목적 코드, object code로 변환해주는 역할을 수행한다. 각각의 특징을 살펴보면 컴파일러는 소스 코드 전체를 목적 코드로 바꿔주고 컴퓨터에서 실행 가능하도록 한다. 쉽게 말해서 사람이 하는 말을 처음부터 끝까지 들은 후에 작업을 수행하는 것이다. 다음으로, 인터프리터는 소스 코드 한 줄 마다 번역함과 동시에 실행하는 작업을 수행한다. 쉽게 말해서 사람의 말을 동시통역 해준다고 이해하면 된다. 이때, 인터프리터는 줄 단위로 바로바로 프로그램이 실행되기 때문에 목적 프로그램이 따로 생성되지는 않는다. 인터프리터는 컴파일의 과정이 없는 것이다.

컴파일러

  1. 소스 코드 전체를 목적 코드로 번역하고 그 결과를 한 번에 실행
  2. 번역과 실행 작업이 따로 진행된다. 번역의 과정은 오래 걸리지만, 실행의 과정은 빠르다.
  3. 실행 프로그램이 따로 생성된다.

인터프리터

  1. 소스 코드 한 줄 마다 번역과 실행이 동시에 이루어진다
  2. 줄 단위로 진행되어 시분할 시스템에 유용하다.
  3. CPU 사용 시간의 낭비가 크다.
  컴파일러 (Compiler) 인터프리터 (Interpreter)
번역 단위 전체 한 줄 마다
실행 속도 빠름 느림
번역 속도 느림 빠름
목적 코드 생성 O 생성 X
예시 C, C++, Java Compiler Python, JavaScript, Java Interpreter

위의 표를 보면 실행 속도와 번역 속도에 차이가 있음을 볼 수 있다. 인터프리터는 한 줄, 행마다 번역을 하기 때문에 빠르지만, 프로그램 전체적으로 봤을 때는 줄마다 번역->실행, 번역->실행의 과정을 거쳐야하니까 컴파일러보다는 느리게 되는 것이다.

컴파일러와 인터프리터는 다르지만, 확실하게 다르다고 경계선을 그을 수는 없다. 최근에는 구분하지 않는 추세이다.

자바의 실행 원리를 통해 이를 설명하겠다.

자바는 컴파일러 방식과 인터프리터 방식을 모두 채택하고 있다. .java 파일을 javac 명령어를 통해 컴파일하면 바이트 코드로 작성된 .class 파일로 변환한다. 그러고 난 다음 인터프리터가 .class 파일의 코드를 한 줄 마다 읽어내려가면서 실행하는 원리이다. 파이썬 또한 마찬가지다. 인터프리터 언어라고 공식 홈페이지에 표기는 되어있지만, 프로그래머가 작성한 코드를 바이트 코드로 컴파일하고 VM(Virtual Machine)에서 라이브러리 모듈을 결합하여 변환된 바이트 코드를 실행하는 방식이다.

공부함에 있어서 프로그래밍 언어를 어떻게 컴퓨터가 이해하는지 간단하게 설명하며 컴파일러와 인터프리터를 알아보았다. 어떠한 언어가 컴파일러인지, 인터프리터인지 명확하게 구분하는 것은 중요하지 않고 컴파일러와 인터프리터 각각의 원리 자체가 중요하다고 생각된다.

※ 본 게시글은 공부하면서 작성한 내용이라, 틀린 점이 있을 수 있습니다. 질문 사항이나 틀린 부분은 댓글을 남겨주시기 바랍니다.

댓글