Spec 0008 — performance measurement report¶
Generated by cmd/afmpeg-bench — WASM (afmpeg) vs native ffmpeg on the same host, same jobs. Source fixture: testsrc2 320×240 @25fps 3s + sine (H.264/AAC). All WASM I/O is in-memory (afero); native writes temp files. Median of 3 runs.
Host¶
| When | 2026-07-05T06:41:33Z |
| Platform | linux/amd64, 8 CPUs |
| Go | go1.26.4 |
| Native | ffmpeg version 6.1.1-3ubuntu5 Copyright © 2000-2023 the FFmpeg developers |
| LGPL module | /home/matt/workspace/phpboyscout/ffmpeg-wasi/dist-wasmcheck/ffmpeg-wasi-lgpl.wasm |
| GPL module | (not provided) |
| Native driver | /home/matt/workspace/phpboyscout/ffmpeg-wasi/dist-native/driver |
Workloads — WASM vs native¶
The native multiple is WASM-libx264 ÷ native-libx264 (same encoder — the honest wasm overhead).
| Workload | WASM openh264 | WASM libx264 | Native libx264 | Native multiple |
|---|---|---|---|---|
| transcode | 2.52 s | — | 162 ms | — |
| reel | 15.61 s | — | 390 ms | — |
- transcode — decode → scale 160 → H.264/AAC mp4 (encode-dominated)
- reel — two inputs → xfade + amix → H.264/AAC mp4 (filter + encode, keyrx-shaped)
Native backend (Backend B) — WASM vs native engine¶
Same openh264 encoder, same jobs; the native driver serves afero over IPC.
| Workload | WASM openh264 | Native driver | Speedup |
|---|---|---|---|
| transcode | 2.52 s | 52 ms | 48.1× |
| reel | 15.61 s | 268 ms | 58.2× |
The native driver also runs through the identical RunJob API — only the backend (WithBackend) differs; results are byte-compatible.
Fleet throughput (instance-level parallelism)¶
4 transcode jobs (x264 ultrafast), one Runtime (serial) vs a pool of 8 Runtimes:
| Mode | Wall clock | Throughput |
|---|---|---|
| Serial (1 Runtime) | 10.15 s | 0.4 jobs/s |
| Fleet (8 Runtimes) | 2.96 s | 1.4 jobs/s |
Speedup: 3.4× across 8 cores.
Thumbnail (frames op — decode + scale, minimal encode)¶
| WASM | Native | Native multiple | |
|---|---|---|---|
| single frame @2s → png | 190 ms | 75 ms | 2.5× |
Caveats¶
- Not apples-to-apples beyond the encoder. WASM is single-threaded and
--disable-asm; native ffmpeg uses all cores + SIMD. The multiple is an upper bound on the gap, not a like-for-like. - I/O differs by design — WASM keeps everything in afero (RAM); native uses temp files.
- openh264 ≠ libx264 in speed and quality/size; the openh264 column is informational.
- The
-Ozvs-O2/-O3module-build axis (spec 0008 §3.2) needs a rebuilt module and is not measured here.