컴파일러
- 전체 변환: 소스 코드 전체 읽어 한 번에 기계어로 번역. 변환 과정 거친 후 생성된 기계어 코드를 실행.
- 속도: 컴파일 과정은 시간이 걸리지만, 변환된 코드는 직접 실행되므로 실행 시간 빠름.
- C, C++, Rust, Go
- 코드 수정시 컴파일 과정 필요.
인터프리터
- 한 줄씩 변환: 소스 코드 한 줄씩 읽어 가며 바로 기계어로 변환하고 실행.
- 속도: 컴파일 단계 없어 초기 단계는 빠름. 전체 코드 실행 시간은 컴파일러 사용하는것 보다 느릴 수 있다. 코드 실행할 때마다 변환과정 거치기 때문.
- 코드 수정시 컴파일 과정 불필요.
모두 고수준 언어를 기계어로 변환한다는 공통점 있다.
JIT 컴파일러
JIT 컴파일러는 인터프리터와 컴파일러 중간 형태
- 코드 분석: 실행 시점에 코드 분석하여, 어떤 부분이 가장 자주 실행되는지(hot spot) 판단. (즉, 실행전 코드를 분석하지는 않음)
- 동적 컴파일: 분석 결과에 기반하여, 자주 실행되는 코드(핫 스팟)만 선별적으로 기계어로 변환. 이과정은 프로그램 실행중에 실시간으로 이루어짐.
- 최적화: 컴파일 과정에서 다양한 최적화 기법 사용(ex, 메모리 접근 패턴을 분석, 가비지 컬렉션의 오버헤드 최소화 등)
- 실행: 컴파일된 기계어 코드를 실행. 프로그램이 실행되면서 새로운 핫 스팟 발견되면, 해당 부분도 JIT 컴파일 통해 최적화됨 ex) JVM, .NET, V8
자주 사용되는 코드의 실행 속도가 크게 향상되는 것이라는 장점과 컴파일된 코드를 메모리에 저장해 캐싱하기 때문에 인터프리터 방식에 비해 더 많은 메모리 소비하는 단점 있다.