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

247 lines
5.5 KiB
Markdown

---
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]]