왜 프로그램 실행 파일은 코드가 단순한 텍스트임에도 이렇게 클까?

컴퓨터 프로그램은 우리가 작성하는 텍스트 코드로부터 시작됩니다.

간단한 명령어들로 구성된 코드가 어떻게 수백 메가바이트에 달하는 커다란 실행 파일로 변하는 걸까요?

이 질문의 답은 의외로 복잡하지만, 그 원리를 하나씩 살펴보면 이해할 수 있습니다.

1. 코드 그 자체보다 훨씬 더 많은 것

우리가 작성하는 텍스트 코드 자체는 프로그램의 일부분에 불과합니다.

프로그램은 종종 라이브러리, 의존성(dependencies), 모듈, 그리고 프레임워크 같은 추가적인 코드들을 포함합니다.

이 코드들은 다른 사람들이 미리 작성해 둔 기능들인데, 우리가 프로그램을 만들 때 이 기능들을 가져다 씁니다.

예를 들어, 간단한 print() 함수 하나를 쓰더라도, 그 함수 뒤에는 수백 줄의 코드가 숨겨져 있죠.

또한, 프로그램은 여러 플랫폼(예: Windows, macOS, Linux)에서 동작할 수 있도록 여러 아키텍처를 지원하는 경우도 많습니다.

예를 들어, macOS의 유니버설 바이너리(Universal binary)는 x86과 ARM 프로세서를 모두 지원하기 위해 두 가지 버전의 실행 파일을 한 번에 포함합니다.

이러한 기능들이 파일 크기를 크게 늘리는 요인입니다.

2. 컴파일된 코드의 크기

프로그램은 텍스트 코드로 작성되지만, 컴퓨터는 텍스트를 직접 이해하지 못합니다.

컴파일러가 텍스트 코드를 기계어로 변환하여 실행 파일을 만들게 되는데, 이 과정에서 코드의 크기가 상당히 커집니다.

단순한 print("Hello World")라는 한 줄의 명령어도 컴파일되면 수백 개의 기계 명령어로 확장될 수 있습니다.

또한, 프로그램이 다양한 상황에서 안정적으로 작동하기 위해 에러 처리 및 안정성 코드가 추가됩니다.

예를 들어, print() 함수는 출력 장치의 종류, 문자 인코딩, 줄바꿈 처리 등 다양한 상황에 맞춰 동작해야 하기 때문에, 그 뒤에는 많은 추가 코드가 포함됩니다.

이로 인해 컴파일된 프로그램 파일의 크기는 더욱 커지게 됩니다.

3. 라이브러리와 의존성

현대의 대부분의 프로그램은 외부 라이브러리에 의존합니다.

라이브러리는 이미 개발된 기능을 쉽게 사용할 수 있도록 모아둔 코드 묶음입니다.

예를 들어, 문서를 PDF로 변환하는 프로그램을 만들 때, 우리는 PDF 파일을 처리하는 라이브러리를 가져다 씁니다.

하지만, 그 라이브러리에는 우리가 실제로 사용하지 않는 기능들도 함께 포함될 수 있습니다.

이처럼 불필요한 코드도 실행 파일에 포함되기 때문에 파일 크기가 커지게 됩니다.

또한, 하나의 라이브러리가 다른 라이브러리에 의존하는 경우도 많습니다.

이런 식으로 라이브러리들이 서로 얽히다 보면, 프로그램은 점점 더 많은 코드를 포함하게 됩니다.

4. 런타임과 환경 의존성

일부 프로그램은 **런타임(runtime)**이라는 실행 환경을 함께 포함합니다.

예를 들어, JavaPython 같은 언어로 작성된 프로그램은 해당 언어의 런타임 환경이 필요합니다.

이 런타임은 프로그램이 실행되기 위해 필요한 필수적인 요소들을 제공하는데, 이러한 런타임이 프로그램 파일에 포함되면 파일 크기가 더 커지게 됩니다.

Pandoc 같은 프로그램의 경우, 모든 의존성을 하나의 바이너리로 묶어 제공하기 때문에 실행 파일이 매우 클 수 있습니다.

이는 사용자가 추가로 라이브러리를 설치하지 않고도 프로그램을 바로 실행할 수 있게 해주지만, 그 대신 파일 크기가 커지는 단점이 있습니다.

5. 멀티미디어 파일과 기타 리소스

프로그램에는 단순한 코드뿐만 아니라 이미지, 비디오, 오디오 같은 리소스 파일도 포함될 수 있습니다.

특히 게임이나 그래픽 프로그램은 이런 멀티미디어 파일들이 많아서 파일 크기가 매우 커질 수 있습니다.

이러한 리소스 파일들은 프로그램과 함께 압축되어 실행 파일에 포함되기 때문에, 코드보다 훨씬 더 많은 공간을 차지하게 됩니다.

또한, 프로그램은 데이터를 더 빠르게 처리하기 위해 미리 생성한 데이터 테이블이나 룩업 테이블을 사용할 수 있습니다.

이런 테이블들은 프로그램이 실행될 때 속도를 높이기 위해 사용되지만, 그 자체로는 많은 저장 공간을 차지하게 됩니다.

예를 들어, 마이크로소프트 워드 파일을 PDF로 변환하는 프로그램은 워드 파일의 구조와 PDF 파일의 구조에 대한 정보를 미리 가지고 있어야 하므로, 그 정보를 저장하는 데 많은 공간이 필요합니다.

6. 최적화 부족

현대의 저장 장치와 메모리는 매우 저렴하고 용량이 크기 때문에, 많은 개발자들이 프로그램 크기를 줄이기 위한 최적화에 큰 신경을 쓰지 않습니다.

과거에는 하드웨어의 성능과 용량이 제한적이어서, 개발자들은 코드의 크기를 최소화하기 위해 많은 노력을 기울였지만, 요즘은 더 많은 기능을 빠르게 개발하는 데 초점을 맞추는 경향이 있습니다.

이로 인해 프로그램에는 불필요한 코드나 사용되지 않는 라이브러리가 포함될 수 있으며, 이런 요소들이 쌓이다 보면 파일 크기가 커지게 됩니다.

개발자들이 최적화를 통해 파일 크기를 줄일 수 있더라도, 많은 경우에는 그 시간과 노력을 다른 기능 개발에 투자하는 것이 더 효율적이기 때문에, 파일 크기 줄이기는 우선순위에서 밀리게 됩니다.

결론: 왜 프로그램 크기가 커질 수밖에 없을까?

결론적으로, 프로그램이 단순한 텍스트 코드로만 구성된 것이 아니라는 점이 핵심입니다.

프로그램은 다양한 라이브러리, 멀티미디어 파일, 런타임 환경 등을 포함하고 있으며, 이러한 요소들이 파일 크기를 크게 증가시킵니다.

또한, 컴파일 과정을 거치면서 코드가 기계어로 변환되고, 이 과정에서 추가적인 명령어와 에러 처리 코드들이 포함되면서 실행 파일의 크기가 더 커지게 됩니다.

현대의 저장 장치 용량과 메모리 성능이 워낙 뛰어나기 때문에, 개발자들은 파일 크기를 줄이는 최적화보다는 더 많은 기능을 추가하는 데 집중하는 경향이 있습니다.

이로 인해 프로그램 크기가 커지게 되지만, 대부분의 경우 이는 큰 문제가 되지 않습니다.

다만, 임베디드 시스템이나 대역폭이 제한된 환경에서는 크기를 줄이는 것이 중요한 과제가 될 수 있습니다.