Performance Profiling Wasm — WebAssembly

Performance Profiling WebAssembly Wasm memang cepat, tapi "berapa cepat?" dan "bisa lebih cepat?" memerlukan pengukuran yang akurat. Profiling membantu…

Performance Profiling WebAssembly

Wasm memang cepat, tapi "berapa cepat?" dan "bisa lebih cepat?" memerlukan pengukuran yang akurat. Profiling membantu menemukan bottleneck dan mengoptimasi di tempat yang tepat.

Benchmarking Basics

// JavaScript: gunakan performance.now()
function benchmark(fn, iterations = 1000) {
  // Warmup
  for (let i = 0; i < 10; i++) fn();

  const start = performance.now();
  for (let i = 0; i < iterations; i++) fn();
  const elapsed = performance.now() - start;

  return {
    total: elapsed.toFixed(2) + "ms",
    perCall: (elapsed / iterations).toFixed(4) + "ms",
  };
}

// Bandingkan JS vs Wasm
const jsResult = benchmark(() => jsFibonacci(40));
const wasmResult = benchmark(() => wasmFibonacci(40));

console.table({ js: jsResult, wasm: wasmResult });

Chrome DevTools Profiling

// 1. Performance tab → Record
// 2. Jalankan Wasm code
// 3. Stop recording

// Di flame chart, Wasm functions muncul sebagai:
// - Nama fungsi (jika compile dengan debug symbols)
// - "wasm-function[42]" (tanpa debug symbols)

// Tips: Compile dengan debug info
// Rust:
wasm-pack build --dev  // include debug symbols

// C++:
emcc -g math.c -o math.js  // include DWARF debug info

Wasm-specific Optimizations

// 1. Minimize JS↔Wasm calls
// ❌ Slow: banyak crossing
for (let i = 0; i < 1000000; i++) {
  wasmModule.processPixel(pixels[i]);
}

// ✅ Fast: satu kali crossing, batch processing
wasmModule.processAllPixels(pixelBuffer, 1000000);

// 2. Use SharedArrayBuffer (zero-copy)
// ❌ Slow: copy data ke Wasm memory
const copy = new Uint8Array(wasmMemory.buffer);
copy.set(largeArray);

// ✅ Fast: shared memory, no copy
const shared = new SharedArrayBuffer(largeArray.byteLength);
new Uint8Array(shared).set(largeArray);
// Pass shared buffer ke Wasm

Rust-specific Optimizations

# Cargo.toml — production optimizations
[profile.release]
opt-level = 3        # maximum optimization
lto = true           # link-time optimization
codegen-units = 1    # better optimization, slower compile
strip = true         # strip debug symbols

# wasm-opt (post-processing)
wasm-opt -O3 -o output.wasm input.wasm
# Bisa mengurangi size 10-20% dan meningkatkan speed

Size Optimization

# Cek ukuran Wasm
ls -lh pkg/module_bg.wasm

# Analisis apa yang memakan space
cargo install twiggy
twiggy top module_bg.wasm
# Menunjukkan fungsi/data terbesar

twiggy dominators module_bg.wasm
# Menunjukkan dependency tree

# Contoh output:
# 45% - alloc::string::String methods
# 20% - serde_json parsing
# 15% - core::fmt (formatting)
# → Hint: kurangi penggunaan String dan serde jika mungkin

Key Metrics

Yang akan kamu pelajari