Skip to main content

컴파일러 보다 인터프리터가 빠르다고요?

총 투표 수: 0 생성자: 현우 채 카테고리: Build, JS, Optimization 주차: 10주차

1000.png

오늘의 목표! 위 사진을 이해시켜드리겠습니다.

-1. 더 빠른 인터프리터 Javascript !

  • Javascript는 계산 위주의 작업에 약하다
  • Javascript는 JIT 컴파일러를 사용한다
  • JavaScript는 자주 쓰는 코드를 캐싱해서 빠르다
  • JS는 인터프리터라 느리다
  • 근데 왜 Node.js 서버가 유행이지..?

$$

뭔소리지..?

$$

이제 알아보도록 하자 😁

0. 발표 개요

오늘 이야기할 것

  1. 컴파일러 vs 인터프리터 (기초 개념 정리)
  2. 인터프리터는 진짜 느릴까?
  3. JS 엔진(V8)은 이 문제를 어떻게 풀었을까?
  4. 그래서 개발자는 무엇을 하면 좋을까?

1. 컴파일러 vs 인터프리터

컴파일 후 실행 파일을 생성하는가? 메모리에 바로 적재하는가?

1-0 용어 정리

컴파일소스코드를 기게어 혹은 기계어와 유사한 low level까지 해석하는 과정
Bytecode /
IR (Intermediate Representation)가상머신이 이해할 수 있는 중간 레벨로 컴파일 한 코드
Native code / 기계어CPU가 직접 해독하고 실행할 수 있는 비트 안뒤(0과 1)로 쓰인 컴퓨터 언어

1-1. 컴파일러 (C, C++)

1001.png

프로그래밍 언어(C, C++)를 기계어로 빠르게 컴파일할 수 있도록 미리 번역해둔 프로그램

  • 실행 전에 전부 변환
  • 실행 속도 빠름
  • 실행 파일 생성됨

컴파일 과정

  1. 전처리기: 컴파일하기 좋은 형태로 변환 (define)
  2. 컴파일러: 고급언어 → 저급 중간 표현(IR) or 어셈블리 코드로 변환
    1. 저급 중간 표현(IR): LLVM 등…
    2. 최적화까지 포함 (죽은 코드 제거, 루프 최적화 등)
  3. 어셈블러: 어셈블리 코드 → 기계어(obj 파일)
  4. 링커: 여러 obj 파일 + 라이브러리 → 하나의 실행 파일 (out, exe 등) / 실제 주소 배정

1-2. 인터프리터

1002.png

고급언어 해석 후 바로 메모리에 적재

  • 실행 파일 없음
  • 유연함, 디버깅 쉬움
  • ❌ 같은 코드도 매번 해석 → 느림

인터프리팅 과정

한 줄 한 줄 해석 → 메모리에 적재 (실행)

1-3. 비교해보자

컴파일러인터프리터
실행 전에 전부 변환한 번에 한 줄씩 변환 (런타임)
실행 속도 빠름같은 코드도 매번 해석 → 느림
실행 파일 생성됨실행 파일 없음 (메모리에 바로 적재)
실행 환경마다 컴파일 필요실행 환경에 맞게 알아서 컴파일
실행 파일만 필요런타임 엔진(인터프리터) 필요 (Node.js / JVM 등)

2. 인터프리터는 진짜 느릴까?

2-1. JIT 컴파일이란

1003.png

컴파일러 + 인터프리터 = 중간 단계까지 컴파일 하자

  • 컴파일하기 쉬운 형태인 Bytecode (IR) 로 미리 변환
  • 런타임에 바이트코드 → 기계어(native code) 번역
    • 한 줄 한 줄 컴파일 → 결과적으로 사용되는 부분만 컴파일
  • 바이트코드 → 기계어(native code) 캐시에 저장
    • 이미 번역한 컴파일 과정을 반복하지 않기 위해 사용

2-2. Adaptive Compilation (Adaptive JIT)

1004.png

실행초기에는 인터프리터로 실행하고, 자주 호출되는 메소드나 반복되는 코드를 검출하여 이런 코드만 컴파일하는 방식

런타임에 얻은 정보로 컴파일 하자!! 런타임 상황에 맞도록 최적화!

Adaptive JIT: JIT 인터프리터 + 런타임 최적화 컴파일러

코드가 사용되었을 때, 즉시 컴파일 X, 여러번 호출 된 후 지연시켜 컴파일. (Lazy Compilation)

프로그램이 실행될 때, 일부 부분만 많이 사용되는 특징이 있음 (80/20 법칙)

→ 런타임에서 얻을 수 있는 정보로 최적화 하기 때문에, 정적컴파일 보다 성능이 향상되는 경우도 있다고 함.

3. 현대 JS 엔진의 핵심: JIT 컴파일

JS 엔진의 진화: 인터프리터 + 컴파일러의 결합

JavaScript는 전통적인 인터프리터의 단점(느린 속도)을 극복하기 위해 JIT (Just-In-Time) 컴파일 방식을 사용합니다.

1000.png

1005.png

3.1 🌟 V8 엔진 (Chrome, Node.js)의 4단계 실행 과정:

  1. 파싱 (Parsing): JS → AST (추상 구문 트리) 변환 (코드 구조 분석)
    1. 렉싱 / 토크나이징 : 코드를 의미있는 조각으로 나눔 → 이때 (렉시컬) 스코프 결정
    2. Abstract Syntax Tree (AST) : 코드를 트리구조로
  2. 바이트코드 생성 & 실행 (Ignition 인터프리터):
    • AST → 바이트코드 변환
    • Ignition 인터프리터 : 바이트코드 실행 (빠른 초기 실행 담당)
  3. 프로파일링 (Profiling):
    • 런타임 시 "자주 실행되는 코드" (Hot Code) 모니터링 (예: 반복문 내부의 함수)
  4. 최적화 컴파일 (TurboFan 컴파일러):
    • Hot Code만 JIT 컴파일러인 **TurboFan (Adaptive JITC)**에게 보냅니다.
    • TurboFan은 이 코드를 **가장 빠르고 최적화된 기계어 코드 (Native Code)**로 변환
    • 다음부터 이 코드가 실행될 때는 번역 과정 없이 기계어 코드가 직접 실행

3.2 어떻게 속도가 빨라지는가?

function add(a, b) {
return a + b;
}

let sum = 0;
for (let i = 0; i < 100000; i++) {
sum += add(1, 2);
}

Adaptive JIT (적응형 JIT)란? - GPT

상세 설명 - GPT

3.2-1. Ignition 인터프리터

; 함수 add(a, b)
LOAD_ARG a ; a를 레지스터에 로드
LOAD_ARG b ; b를 레지스터에 로드

CHECK_TYPE a ; a가 number인지?
CHECK_TYPE b ; b가 number인지?
; (아닐 수도 있으니까 매번 검사) - slow case

ADD_GENERIC a, b ; + 연산 수행
; (숫자 덧셈인지, 문자열 결합인지 런타임에 결정)
RETURN
SET sum = 0
SET i = 0

LOOP_START:
CHECK i < 100000 ; 반복 조건 검사
IF_FALSE GOTO END

CALL add(1, 2) ; 함수 호출 (비용 있음)
LOAD result

CHECK_TYPE sum ; sum 타입 확인
ADD_GENERIC sum, result
; 연산 의미를 매번 판단 (타입 별 체크)

INCREMENT i
GOTO LOOP_START

END:

3.2-2 TurboFan 컴파일러

; add 함수는 인라인 처리됨
; add(1, 2) → 3

SET sum = 0
SET i = 0

LOOP_START:
CMP i, 100000
JGE END

ADD sum, 3 ; 타입 체크 없음
; 함수 호출 없음
; 바로 CPU 덧셈
INC i
JMP LOOP_START

END:

3.2-3 만약에 이랬다면?

sum += add(1, "2");

3.3 Adaptive JIT 컴파일의 효과

구분전통적인 인터프리터현대적인 JIT (JS)
코드 변환실행 시 매번 바이트코드 변환자주 쓰이는 코드는 영구적인 기계어로 변환
속도느림초기 실행은 느리지만, 반복 실행 시 매우 빠름 (컴파일러급 성능)
오류 검출해당 줄에 도달해야 발견(동일) 실행 중 발견되나, 최적화 중에도 오류 감지 가능
개발 편의성높음높음 (인터프리터의 유연성을 유지)

4. 그래서 개발자는 무엇을 하면 좋을까?

1. Hotspot을 만들자

  • 작은 함수
  • 반복 호출 구조

2. 타입 안정성

  • 같은 변수에 다른 타입 넣지 않기
  • hidden class 깨지지 않게

3. 불필요한 추상화 주의

  • 과도한 고차 함수
  • 동적 구조 변경

참고

https://velog.io/@wish/JavaScript%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%90%A0%EA%B9%8C

https://prod.velog.io/@seorim6417/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%97%94%EC%A7%84%EC%9D%98-%EC%B5%9C%EC%A0%81%ED%99%94-%EB%B0%A9%EC%8B%9D-AJITC

아무거나 적어보자