--- id: perf-v8-optimization title: V8 Optimization — Hidden class / Inline cache / Hot path category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [performance, v8, javascript, vibe-coding] tech_stack: { language: "JS / TS", applicable_to: ["Backend", "Frontend"] } applied_in: [] aliases: [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 안정 ```ts // ❌ 다른 순서 / 다른 필드 = 다른 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 함수 ```ts // ❌ 다양한 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 ```ts // ✅ 빠름 class User { constructor(public id: string, public email: string) {} } // ⚠️ 느릴 수 있음 const user = { id, email, age, ...rest }; ``` → Class 가 hidden class 강제. ### Tight loop ```ts // ✅ 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 ```ts // ❌ 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 (대량 숫자) ```ts // ✅ const arr = new Float32Array(1_000_000); arr[0] = 1.5; // 빠름, 작은 메모리, GC 압력 적음 // ❌ 일반 array const arr = new Array(1_000_000).fill(0); ``` ### String concatenation ```ts // ✅ 큰 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 줄이기) ```ts // ❌ 매 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 작은 함수 ```ts // V8 가 작은 함수 자동 inline. 너가 따로 inline 할 필요 X. // 단 monomorphic 강한 경우. ``` ### Map vs Object (key set 자주 변경) ```ts // ✅ 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) ```bash node --trace-deopt app.js # 어느 함수가 deopt 됐는지 ``` ```bash node --trace-opt app.js # Optimize / 다시 ``` ### Hot function 측정 ```ts 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 ```bash 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. ## 🔗 관련 문서 - [[Perf_Node_Profiling]] - [[Perf_Web_Memory_Leak]] - [[Perf_React_Reconciler]]