Deoptimization 로그 분석

rada·2025년 4월 6일
0

개발

목록 보기
33/43

🧨 Deoptimization 로그 분석 +

🚀 Real-world V8 성능 튜닝 사례

🧨 1. Deoptimization 로그 분석

▶️ 코드 예제 (Node.js 기준)

function sum(x, y) {
  return x + y;
}

%PrepareFunctionForOptimization(sum);
sum(1, 2);   // warm-up
%OptimizeFunctionOnNextCall(sum);
sum(1, 2);   // optimized

sum("a", 1); // triggers deopt

🧪 실행 방법

node --allow-natives-syntax --trace-opt --trace-deopt test.js
#### 🔍 로그 해석
bash
복사
편집
[optimizing 0x12345678 <JSFunction sum (sfi = 0x...)> - took 0.23, ...
[deoptimizing (DEOPT eager): begin 0x12345678 sum @ 0]
  ; reason: wrong type
  ; deopted at <unknown>:1:10
  ; source position: 15
[deoptimizing: end 0x12345678 sum @ 0 => node=3, pc=0x..., caller=0x...]

💡 분석 포인트

  • DEOPT eager: 즉시 deopt 처리 (speculative 최적화 깨짐)
  • reason: wrong type: x + y가 float64 연산으로 최적화되었는데, 문자열 들어옴
  • node=3: TurboFan 노드 번호 (IR 그래프에서 위치)
  • 이 시점 이후 V8은 이 함수에 대해 추가 최적화 시도 억제 가능

🚀 2. Real-World V8 성능 튜닝 사례

📦 예제: JSON 파서 성능 튜닝 (Node.js 실전에서 있었던 일)

⚠️ 문제 코드

function parseData(str) {
  return JSON.parse(str);
}
  • 간단한 코드지만, 엄청난 양의 데이터를 처리할 때 예상보다 느림
  • str이 때때로 undefined/null 등으로 들어올 수 있었음

🔍 분석 플래그 사용

node --trace-opt --trace-deopt parser.js
[deoptimizing (<DEOPT eager): reason: wrong value (undefined)]

✅ 해결책: 타입 가드 추가

function parseData(str) {
  if (typeof str !== 'string') return null;
  return JSON.parse(str);
}

Deopt 방지 → TurboFan이 더 aggressive하게 최적화 가능

결과: 처리 속도 2~3배 향상

📦 예제: 데이터 접근 최적화 (대규모 로그 처리기)

⚠️ 문제 코드

function getIP(log) {
  return log.meta && log.meta.ip;
}

log.meta가 없는 경우 많았고, Optional chaining 사용 불가한 구식 환경

🔍 로그 분석 결과:

reason: unstable map

log.meta의 구조가 매번 다름 → Hidden Class/IC 깨짐

✅ 해결책

function getIP(log) {
  const meta = log.meta || {};
  return typeof meta.ip === 'string' ? meta.ip : null;
}

안정적인 객체 구조 확보 → IC 안정화 → 성능 30% 향상

📦 예제: 커스텀 sort 성능 문제

arr.sort((a, b) => {
  if (a.score > b.score) return -1;
  if (a.score < b.score) return 1;
  return 0;
});

🚨 문제

  • 이 comparator 함수가 매번 새로 정의됨
  • V8은 이걸 익명 함수로 취급 → 인라이닝 X, IC X

✅ 해결

function compareScores(a, b) {
  return b.score - a.score;
}
arr.sort(compareScores);
  • Named function으로 변경 → IC 히트 + 인라이닝 가능
  • 단순 연산으로 변경 (b - a) → TurboFan strength reduction

🛠 보너스: 빠른 성능 튜닝 체크리스트

항목확인
객체 구조 일관성 유지
타입 고정 및 가드 사용
Hot path 분리
반복되는 로직은 함수 분리 (인라이닝 유도)
배열은 Packed 상태 유지
arguments 대신 ...args
실전 테스트 전 warm-up → optimize → 측정
profile
So that my future self will not be ashamed of myself.

0개의 댓글