컴파일 vs. 인터프리터

컴파일 vs. 인터프리터

숙련된 프로그래머 중에서 컴파일되는 프로그래밍 언어와 인터프리터되는 프로그래밍 언어의 차이점을 모르는 사람은 없을 것이다. 인터프리터되는 언어는 비교적 빠른 속도로 프로그램을 짤 수 있고, 결과를 쉽게 확인할 수 있다. 반면 컴파일되는 언어는 수행 속도가 빠르다. 프로그래밍 언어를 선택할 때 가장 먼저 적용해봐야 할 잣대 중에 하나는 해당 언어의 컴파일러나 인터프리터가 존재하느냐는 것이다.


경우에 따라서는 컴파일러와 인터프리터가 모두 존재할 수도 있고, 두 가지가 혼합된 형태일 수도 있다. 예를 들어 자바의 경우 자바 프로그램이 바이트코드(bytecode)로 컴파일되고, 자바 가상 머신(Java Vir tual Machine)에 의해서 다시 인터프리트되는 것이 일반적이다. 그러나 모바일 컨텐츠나 게임을 만들 때는 자바로 프로그램을 만들고 수행 속도 향상을 위해 타겟 플랫폼에 맞춰 미리 컴파일(AOTC, Ahead Of Time Compilation)하는 경우가 흔한데, 이는 자바 언어의 컴파일러라고 볼 수 있다. 비슷한 예로, 수행되기 직전에 머신 코드로 컴파일되는 JIT(Just In Time) 컴파일 방법도 있다.

같은 언어로 프로그래밍되더라도 컴파일러냐 인터프리터냐에 따라 성능과 사용성이 크게 달라진다. 일반적으로 컴파일되는 프로그래밍 언어는 두 가지 장점이 있는데, 하나는 수행 속도 향상이고 또 하나는 소스코드의 암호화(obfuscation)이다. 컴파일러가 인터프리터에 비해 같은 프로그램을 빠른 속도로 수행하게 만드는 것은 분명하다. 컴파일 시간은 런타임과 별도로 한 번만 수행되면 되기 때문에 각종 최적화(optimization) 기술을 적용하기가 유리하다. 물론 최근에는 자바 가상 머신(JVM)이 이런 컴파일러의 최적화 기술을 빌려와 동적으로 머신 코드를 생성하는 기술(adaptive compilation or HotSpot)을 도입했지만, 일부 최적화 기술은 그 특성상 많은 시간이 걸리기 때문에 같은 언어를 컴파일하여 얻어진 프로그램보다 빠를 수는 없다.

또 하나의 차이점은 소스코드를 얼마나 알아보기 힘들게 만들 수 있는가이다. 컴파일된 프로그램의 경우 해당 고급 언어의 특징이 거의 사라진, 기계어로 번역되어 있기 때문에 머신 코드를 바탕으로 원본 소스코드를 복원해 낼 수 있는 가능성은 거의 없다. 반면에 인터프리터되는 언어는 수행을 위해 소스코드가 건네져야 하므로, 소스코드 공개 의사가 없는 상업적인 프로젝트의 경우 해결하기 힘든 문제에 봉착할 우려가 있다.

필자도 프로젝트를 수행하면서 소스코드의 비밀 유지 때문에 많은 문제를 겪었다. 필자는 디지털 텔레비전을 위한 미들웨어 플랫폼을 만드는 일을 했었는데, 여기서 하드웨어와 운영체제를 바탕으로 시스템을 빌드하는 일은 C 언어로 했지만, 해당 플랫폼이 자바를 기반으로 하기 때문에 API를 자바 기반으로 작성해야 했다. 문제는 이를 배포하기 위해 바이너리를 줘야 하는데, C 언어로 컴파일된 바이너리는 문제가 없었지만 자바로 작성한 클래스를 배포할 때 문제가 생겼다.

자바의 경우 일단 한 번 바이트코드로 컴파일된 후에 자바 가상 머신 위에서 인터프리트되지만, 바이트코드는 가상 머신에서 동작하는 일종의 기계어임에도 불구하고 실제 기계어인 인텔이나 ARM, PowerPC 등의 어셈블리 언어에 비해서는 대부분의 자바 심볼(symbol)을 보존하고 있는 고급 언어라 할 수 있다. 시중에는 자바의 클래스 파일을 바탕으로 원래의 자바 소스코드를 복원해주는 디컴파일러(decompiler)가 많이 존재한다. 따라서 자바로 만든 프로그램을 배포할 때는 이를 컴파일하여 클래스 파일만 배포하더라도 누군가가 소스코드를 엿볼 수 있다는 불안에 시달려야 하는 것이다.

필자의 회사에서 시도한 첫 번째 방법은 자바 소스코드를 뒤죽박죽으로 만들어 주는 프로그램(Java Obfuscator)을 이용하는 것이었다. 이 프로그램은 원래 자바 프로그램의 의미를 훼손시키지 않고, 단순히 변수 이름과 클래스 이름을 a, b, c 등의 의미 없는 이름으로 바꾸어서 해당 프로그램을 해독하기 힘들게 만들어 준다. 그러나 이 방법도 완벽하진 않았다. 클래스와 변수 이름을 이상하게 바꿀 수는 있어도, 외부로 참조해야 하는 API의 이름을 바꿀 수는 없을 뿐더러, 비교적 제한된 애플리케이션 범주라면 숙련된 자바 프로그래머의 경우 바이트코드에서 복원된 소스코드를 읽는 것이 어렵지 않기 때문이다.

이 미들웨어는 결국 자바 클래스 파일을 JAR가 아닌 별도의 암호화 방법으로 압축했다. 그리고 이 클래스를 읽는 방법은 비밀에 붙인 채, C 언어로 암호화된 클래스 파일을 해석하여 원래의 클래스로 복원하여 자바 가상 머신에 로딩해 주는 방법을 사용하게 되었다. 이와 달리 일반적인 애플리케이션의 경우 인터프리팅되는 언어를 사용한 프로그램의 소스코드가 공개되지 않기를 바란다면, 이는 패키지로 만들어서 서버에서 수행한 후 결과만 웹 브라우저를 통해 알려주는 서블릿(servlet) 형태가 되어야 할 것이다.

결국 프로젝트에 있어서 성능이 중요하거나 소스코드 유출 방지가 높은 우선순위를 차지한다면, 인터프리터 언어가 주는 유용성, 개발의 편리성을 감안하더라도 치러야 할 대가가 크다는 사실을 알 수 있다. 따라서 특정 프로그래밍 언어를 선택하기 위해서는 해당 프로그래밍 언어의 컴파일러가 존재하는지, 혹은 인터프리터가 존재하는지를 확인해보는 것이 필요하다.

by tobby48 | 2007/03/09 01:28 | Etc | 트랙백 | 덧글(0)

트랙백 주소 : http://tobby48.egloos.com/tb/994526
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

<< 이전 페이지     다음 페이지 >>