Files
2nd/10_Wiki/Topics/Coding/Perf_V8_Optimization.md
T
2026-05-09 21:08:02 +09:00

5.5 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
perf-v8-optimization V8 Optimization — Hidden class / Inline cache / Hot path Coding draft B conceptual 2026-05-09 2026-05-09
performance
v8
javascript
vibe-coding
language applicable_to
JS / TS
Backend
Frontend
V8
hidden class
monomorphic
inline cache
deopt
Sparkplug
TurboFan

V8 Optimization

JIT 친화 코드 = 100x 빠름. Monomorphic > polymorphic > megamorphic. Hidden class 안정 + 같은 type 만 + tight loop. 보통 알고리즘 < V8 hint.

📖 핵심 개념

  • Hidden class (Map): object shape — V8 가 cache.
  • IC (Inline Cache): 같은 site 같은 type → fast.
  • Monomorphic / Polymorphic / Megamorphic.
  • Deopt: 다른 type 출현 → JIT 코드 폐기.

💻 코드 패턴

Hidden class 안정

// ❌ 다른 순서 / 다른 필드 = 다른 hidden class
const a = { x: 1 };
a.y = 2;
const b = { y: 2 };
b.x = 1;
// a, b 가 다른 hidden class

// ✅
const a = { x: 1, y: 2 };
const b = { x: 3, y: 4 };
// 같은 hidden class

→ Object literal 시 모든 필드 한 번에. 추가 X.

Monomorphic 함수

// ❌ 다양한 type
function getX(obj) { return obj.x; }
getX({ x: 1 });          // shape A
getX({ x: 1, y: 2 });    // shape B
getX({ x: 1, y: 2, z: 3 }); // shape C
// → polymorphic / megamorphic — 느림

// ✅ 같은 shape 만
class Point { constructor(x, y) { this.x = x; this.y = y; } }
const points = [new Point(1, 2), new Point(3, 4)];
points.forEach(p => p.x);  // monomorphic

Class > 동적 object

// ✅ 빠름
class User {
  constructor(public id: string, public email: string) {}
}

// ⚠️ 느릴 수 있음
const user = { id, email, age, ...rest };

→ Class 가 hidden class 강제.

Tight loop

// ✅
let sum = 0;
for (let i = 0; i < arr.length; i++) {
  sum += arr[i];
}

// ⚠️ functional — V8 가 잘 최적화 하지만 일부 case 느림
const sum = arr.reduce((s, x) => s + x, 0);

→ Hot path = 측정 후 결정.

Avoid deopt triggers

// ❌ try-catch 안 hot loop (V8 옛 — 새 V8 는 OK)
function hot() {
  try {
    for (...) inner();
  } catch (e) { ... }
}

// 새 V8 는 try-catch 거의 무 비용.

// ❌ delete (hidden class 변경)
delete obj.x;

// ❌ undefined / null mix
function add(a, b) { return a + b; }
add(1, 2);
add('x', 'y');  // string concat — deopt

TypedArray (대량 숫자)

// ✅
const arr = new Float32Array(1_000_000);
arr[0] = 1.5;
// 빠름, 작은 메모리, GC 압력 적음

// ❌ 일반 array
const arr = new Array(1_000_000).fill(0);

String concatenation

// ✅ 큰 string
const parts: string[] = [];
for (...) parts.push(line);
const result = parts.join('\n');

// ❌
let result = '';
for (...) result += line;
// V8 가 어느 정도 최적화 하지만 array.join 가 안전.

// ✅ 작은 string
const s = `${a} - ${b}`;  // 일반 OK

Object 재사용 (allocation 줄이기)

// ❌ 매 iteration object 새로
function process(items) {
  for (const it of items) {
    const tmp = { x: it.x, y: it.y };
    use(tmp);
  }
}

// ✅
const tmp = { x: 0, y: 0 };
function process(items) {
  for (const it of items) {
    tmp.x = it.x;
    tmp.y = it.y;
    use(tmp);
  }
}

⚠️ Mutation 주의 — 라이브러리에 안 맞음.

Inline 작은 함수

// V8 가 작은 함수 자동 inline. 너가 따로 inline 할 필요 X.
// 단 monomorphic 강한 경우.

Map vs Object (key set 자주 변경)

// ✅ Map — 동적 key 안정
const m = new Map();
m.set('a', 1); m.set('b', 2); m.delete('a');

// ❌ object — delete 가 hidden class 변경
const o = {};
o.a = 1; delete o.a;

--trace-deopt (debug)

node --trace-deopt app.js
# 어느 함수가 deopt 됐는지
node --trace-opt app.js
# Optimize / 다시

Hot function 측정

const COUNT = 1_000_000;
const arr = Array.from({ length: COUNT }, (_, i) => i);

const t = performance.now();
for (let i = 0; i < arr.length; i++) hotFn(arr[i]);
console.log('avg:', (performance.now() - t) / COUNT, 'ms');

V8 inspector profiling

node --prof app.js
node --prof-process isolate-*.log > profile.txt

또는 위 (Node profiling) 의 0x / clinic.

Algorithm > Micro-opt

Big O 가 99% 의 답.
O(n²) → O(n log n) = 1000x 빠름.
Monomorphic vs polymorphic = 2-10x.

→ 알고리즘 먼저, micro-opt 마지막.

Bun / Deno

Bun = JSC (Safari engine).
Deno = V8 (Chrome engine).

코드 호환 — engine 별 미세 차이.

🤔 의사결정 기준

작업 우선순위
Big O 1순위
Monomorphic / class 2순위
TypedArray (숫자) hot loop
Allocation 줄이기 very hot path
try-catch / delete 이젠 무 의미 (V8 modern)
Inline / unroll 측정 후

안티패턴

  • Algorithm 무시 + V8 trick: O(n²) 가 V8 trick 으로 안 됨.
  • 모든 곳 micro-opt: 가독성 잃음. hot path 만.
  • Object shape 매번 다름: deopt.
  • Ah-hoc benchmark (1번 측정): warmup 필요. 평균.
  • 매 turn V8 update 따라가기: 너무 unstable. 알고리즘 우선.
  • Premature optimization: 측정 X 추측.

🤖 LLM 활용 힌트

  • Big O 우선. micro-opt 는 hot path 측정 후.
  • Monomorphic class > 동적 object.
  • TypedArray = 숫자 큰 array.

🔗 관련 문서