Skip to content

build: add final WebAssembly size optimization - #2909

Open
cpunion wants to merge 3 commits into
xgo-dev:mainfrom
cpunion:codex/wasm-final-size-20261022
Open

cpunion wants to merge 3 commits into
xgo-dev:mainfrom
cpunion:codex/wasm-final-size-20261022

Conversation

@cpunion

@cpunion cpunion commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Adds opt-in -wasm-opt=size and -wasm-strip=none|debug|all for hosted Wasm executables. Final optimization runs after required lowering and before DWARF packaging, with explicit target features and preserved host exports. Outputs are staged with rollback and a manifest containing tool identities, artifact hashes, and raw/gzip sizes. Defaults and development-only optimization gates are unchanged.

With -wasm-opt=size -wasm-strip=debug, default fmtprintf deployment sizes are:

Profile Before After Reduction
W32/WASI 2,371,607 B 1,937,708 B 18.30%
J32/Emscripten 3,139,290 B 3,072,575 B 2.13%
J64/Emscripten 2,908,050 B 2,848,135 B 2.06%

Includes JS, filesystem glue and the new manifest; no -s, DCE or LTO. Baseline: 057851875, excluding #2908. Full measurements and contracts include compression overhead and the Binaryen 132 DWARF pass workaround.

Validation: full platform CI passed, including final-pipeline runtime/browser and DWARF coverage. Local checks also executed 18 size cases, W32/J32/J64 embedded/external DWARF source-line tests, J32/J64 browser reflection and worker FS/GC, and callback/ABI/public-export fixtures.

Part of #2480 and #2679. Stable frame IDs/external PCLN and further runtime/formatting reduction remain.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLGo PR #2909 Review — Final WebAssembly size optimization

Reviewed the full diff: new -wasm-opt/-wasm-strip flags, the Binaryen-backed finalize pipeline (wasm_final.go), the artifact manifest + staged publish with rollback (wasm_manifest.go), the Wasm metadata strip/parse helpers (wasmdebug/metadata.go), and the wiring, docs, CI, and tests.

Overall this is high-quality, well-structured work. The staging-directory design keeps the real output untouched until every step (optimize → validate → PCLN → debug packaging → strip → manifest → publish) succeeds, the rollback logic is correct, and the test suite is unusually thorough — covering missing/wrong-version tool, link/optimizer failures, strip-only encoding preservation, non-file obstructions, and publish rollback. I verified the parsing path (readULEB32/readName/parse/TargetFeatures): ULEB shift/overflow bounds and uint64 length checks are correct, with no out-of-bounds or over-allocation on malformed modules. Documentation in doc/wasm-size.md matches the implementation on every claim I checked (defaults, skip-pass list, EXPORT_ALL=0, manifest fields, publish semantics, links).

The findings below are maintainability/quality suggestions, not defects — nothing blocking.

Minor notes not inlined:

  • -wasm-opt/-wasm-strip valid-value sets are enforced in two places (cmd/internal/flags/wasm.go and validateWasmFinalOptions); adding a third mode means editing both. A shared source would reduce drift. Relatedly, "off" has two representations ("" when the flag is omitted vs "off" when passed explicitly); the manifest normalizes this, so it's harmless today but a small latent trap.
  • wasmArtifact gzips every staged artifact at level 9 (incl. potentially large .debug.wasm) purely to record gzip_bytes. Reasonable as a feature cost, but it's the heaviest step in finalize for large modules — worth a conscious decision if manifests are produced on every build.
  • Security posture is clean under the local-build trust model: tool args are a fixed []string (no shell), feature names passed to --enable-* come from the hardcoded allowlist (never from parsed module bytes), and no secrets/env values are written to the manifest. The recorded tool SHA-256 is logged but not enforced against a pinned value — fine if the version check is considered sufficient.

Comment thread internal/build/wasm_final.go Outdated
Comment thread internal/build/wasm_manifest.go
Comment thread internal/build/wasm_final.go
Comment thread internal/wasmdebug/metadata.go Outdated
@codecov

codecov Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.93750% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/build/wasm_manifest.go 95.62% 6 Missing ⚠️
internal/build/wasm_final.go 96.21% 5 Missing ⚠️
internal/build/build.go 77.77% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

LLGo baseline benchmarks

9b001de13828 | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Text size vs base Build vs base Run vs base
Linux cprintf 8336 B 0 B / +0.0% 387 B 0 B / +0.0% 907.917 ms +26.26 ms / +3.0% (worse) 1.298 ms +54.27 us / +4.4% (worse)
Linux cprintf-lto 8120 B 0 B / +0.0% 368 B 0 B / +0.0% 918.957 ms -107.1 ms / -10.4% (better) 1.368 ms +121.6 us / +9.8% (worse)
Linux fmtprintf 2565720 B +96 B / +0.003742% (worse) 511606 B 0 B / +0.0% 5.551 s -87.63 ms / -1.6% (better) 4.011 ms +142.3 us / +3.7% (worse)
Linux fmtprintf-lto 2008104 B -112 B / -0.005577% (better) 448627 B 0 B / +0.0% 24.273 s +295.5 ms / +1.2% (worse) 3.503 ms -44.83 us / -1.3% (better)
Linux println 246128 B +72 B / +0.02926% (worse) 17756 B 0 B / +0.0% 1.037 s +24.54 ms / +2.4% (worse) 1.599 ms -71.76 us / -4.3% (better)
Linux println-lto 97056 B +16 B / +0.01649% (worse) 15021 B 0 B / +0.0% 1.646 s +56.44 ms / +3.6% (worse) 1.650 ms +27.23 us / +1.7% (worse)
macOS cprintf 50672 B 0 B / +0.0% 4409 B 0 B / +0.0% 664.551 ms -111.8 ms / -14.4% (better) 2.271 ms -340.3 us / -13.0% (better)
macOS cprintf-lto 50592 B -16 B / -0.03162% (better) 161 B 0 B / +0.0% 765.010 ms +3.374 ms / +0.4% (worse) 2.116 ms +73.33 us / +3.6% (worse)
macOS fmtprintf 1687552 B -16 B / -0.0009481% (better) 892440 B 0 B / +0.0% 3.130 s +581.3 us / +0.01857% (worse) 26.863 ms -527.2 us / -1.9% (better)
macOS fmtprintf-lto 1405232 B -16 B / -0.001139% (better) 774684 B 0 B / +0.0% 5.814 s +165.7 ms / +2.9% (worse) 39.007 ms -355.3 us / -0.9% (better)
macOS println 96960 B 0 B / +0.0% 24707 B 0 B / +0.0% 775.017 ms +5.033 ms / +0.7% (worse) 3.039 ms +122.4 us / +4.2% (worse)
macOS println-lto 84288 B 0 B / +0.0% 21864 B 0 B / +0.0% 902.034 ms +5.418 ms / +0.6% (worse) 3.615 ms +1.017 ms / +39.1% (worse)
Windows MinGW cprintf 709632 B 0 B / +0.0% 4390 B 0 B / +0.0% 1.841 s -40.72 ms / -2.2% (better) 4.213 ms +730.3 us / +21.0% (worse)
Windows MinGW cprintf-lto 59392 B 0 B / +0.0% 4342 B 0 B / +0.0% 1.889 s +13.77 ms / +0.7% (worse) 3.381 ms -118.5 us / -3.4% (better)
Windows MinGW fmtprintf 5588480 B 0 B / +0.0% 609462 B 0 B / +0.0% 5.707 s +42.48 ms / +0.7% (worse) 11.770 ms +122.1 us / +1.0% (worse)
Windows MinGW fmtprintf-lto 4232192 B 0 B / +0.0% 556838 B 0 B / +0.0% 13.361 s +217.1 ms / +1.7% (worse) 10.640 ms +25.6 us / +0.2% (worse)
Windows MinGW println 766976 B 0 B / +0.0% 25510 B 0 B / +0.0% 1.834 s -7.54 ms / -0.4% (better) 6.962 ms +166.8 us / +2.5% (worse)
Windows MinGW println-lto 222208 B 0 B / +0.0% 22278 B 0 B / +0.0% 2.326 s +125.2 ms / +5.7% (worse) 7.000 ms +425.2 us / +6.5% (worse)
Windows MinGW 386 cprintf 657920 B 0 B / +0.0% 5608 B 0 B / +0.0% 1.854 s +20.18 ms / +1.1% (worse) 5.080 ms -133.1 us / -2.6% (better)
Windows MinGW 386 cprintf-lto 119296 B 0 B / +0.0% 5112 B 0 B / +0.0% 1.906 s +68.74 ms / +3.7% (worse) 5.011 ms -279.3 us / -5.3% (better)
Windows MinGW 386 fmtprintf 4884992 B 0 B / +0.0% 476862 B 0 B / +0.0% 6.019 s +342.9 ms / +6.0% (worse) 15.619 ms +3.258 ms / +26.4% (worse)
Windows MinGW 386 fmtprintf-lto 4233728 B 0 B / +0.0% 455182 B 0 B / +0.0% 13.175 s +254.2 ms / +2.0% (worse) 12.814 ms -489.5 us / -3.7% (better)
Windows MinGW 386 println 711680 B 0 B / +0.0% 22116 B 0 B / +0.0% 1.820 s +8.801 ms / +0.5% (worse) 8.974 ms +211.9 us / +2.4% (worse)
Windows MinGW 386 println-lto 271872 B 0 B / +0.0% 19628 B 0 B / +0.0% 2.122 s -16.59 ms / -0.8% (better) 8.418 ms -406.5 us / -4.6% (better)
Windows MinGW ARM64 cprintf 720896 B 0 B / +0.0% 4204 B 0 B / +0.0% 2.080 s -25.25 ms / -1.2% (better) 6.370 ms -567.6 us / -8.2% (better)
Windows MinGW ARM64 cprintf-lto 58880 B 0 B / +0.0% 4156 B 0 B / +0.0% 2.100 s -33.74 ms / -1.6% (better) 6.718 ms -241 us / -3.5% (better)
Windows MinGW ARM64 fmtprintf 5498368 B 0 B / +0.0% 517620 B 0 B / +0.0% 5.599 s -182.7 ms / -3.2% (better) 15.309 ms -1.424 ms / -8.5% (better)
Windows MinGW ARM64 fmtprintf-lto 4398592 B 0 B / +0.0% 483424 B 0 B / +0.0% 12.208 s -169.9 ms / -1.4% (better) 14.852 ms -677.6 us / -4.4% (better)
Windows MinGW ARM64 println 773632 B 0 B / +0.0% 24152 B 0 B / +0.0% 2.072 s -27.72 ms / -1.3% (better) 11.197 ms -370 us / -3.2% (better)
Windows MinGW ARM64 println-lto 228352 B 0 B / +0.0% 21404 B 0 B / +0.0% 2.358 s -34.53 ms / -1.4% (better) 10.966 ms -1.184 ms / -9.7% (better)
Windows MSVC cprintf 954368 B 0 B / +0.0% 66003 B 0 B / +0.0% 1.829 s -75.59 ms / -4.0% (better) 3.350 ms -551 us / -14.1% (better)
Windows MSVC cprintf-lto 307200 B 0 B / +0.0% 65971 B 0 B / +0.0% 1.758 s -113.9 ms / -6.1% (better) 3.313 ms -113.7 us / -3.3% (better)
Windows MSVC fmtprintf 5890560 B 0 B / +0.0% 705350 B 0 B / +0.0% 5.577 s +40.14 ms / +0.7% (worse) 12.271 ms -510.4 us / -4.0% (better)
Windows MSVC fmtprintf-lto 4556288 B 0 B / +0.0% 656486 B 0 B / +0.0% 12.223 s -405.2 ms / -3.2% (better) 12.573 ms -116.9 us / -0.9% (better)
Windows MSVC println 1079808 B 0 B / +0.0% 121542 B 0 B / +0.0% 1.755 s -107.2 ms / -5.8% (better) 6.731 ms -299.4 us / -4.3% (better)
Windows MSVC println-lto 542720 B 0 B / +0.0% 118982 B 0 B / +0.0% 2.042 s -60.5 ms / -2.9% (better) 7.319 ms -871 us / -10.6% (better)
Windows MSVC 386 cprintf 566784 B 0 B / +0.0% 3947 B 0 B / +0.0% 1.734 s -233.3 ms / -11.9% (better) 5.821 ms -24.9 us / -0.4% (better)
Windows MSVC 386 cprintf-lto 59904 B 0 B / +0.0% 3901 B 0 B / +0.0% 1.759 s -239.5 ms / -12.0% (better) 5.244 ms -536.7 us / -9.3% (better)
Windows MSVC 386 fmtprintf 4615680 B 0 B / +0.0% 460274 B 0 B / +0.0% 5.503 s -8.498 ms / -0.2% (better) 13.557 ms -703 us / -4.9% (better)
Windows MSVC 386 fmtprintf-lto 3980288 B 0 B / +0.0% 430529 B 0 B / +0.0% 11.926 s +9.014 ms / +0.1% (worse) 15.220 ms +1.419 ms / +10.3% (worse)
Windows MSVC 386 println 623104 B 0 B / +0.0% 20716 B 0 B / +0.0% 1.724 s -54.72 ms / -3.1% (better) 9.755 ms -208.6 us / -2.1% (better)
Windows MSVC 386 println-lto 210944 B 0 B / +0.0% 18829 B 0 B / +0.0% 2.258 s +147.4 ms / +7.0% (worse) 9.480 ms -950.2 us / -9.1% (better)
Windows MSVC ARM64 cprintf 720384 B 0 B / +0.0% 4240 B 0 B / +0.0% 1.847 s -85.71 ms / -4.4% (better) 6.932 ms -547.6 us / -7.3% (better)
Windows MSVC ARM64 cprintf-lto 64512 B 0 B / +0.0% 4140 B 0 B / +0.0% 1.894 s -26.67 ms / -1.4% (better) 7.097 ms -42.4 us / -0.6% (better)
Windows MSVC ARM64 fmtprintf 5494784 B 0 B / +0.0% 517716 B 0 B / +0.0% 5.419 s +3.67 ms / +0.1% (worse) 18.047 ms +149.1 us / +0.8% (worse)
Windows MSVC ARM64 fmtprintf-lto 4405760 B 0 B / +0.0% 484240 B 0 B / +0.0% 12.097 s +182.3 ms / +1.5% (worse) 18.608 ms +412.1 us / +2.3% (worse)
Windows MSVC ARM64 println 775680 B 0 B / +0.0% 24420 B 0 B / +0.0% 1.873 s -40.15 ms / -2.1% (better) 13.606 ms +7.4 us / +0.1% (worse)
Windows MSVC ARM64 println-lto 233472 B 0 B / +0.0% 21796 B 0 B / +0.0% 2.154 s +47.53 ms / +2.3% (worse) 13.266 ms +1.452 ms / +12.3% (worse)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 14.640 ns/op -0.06 ns/op / -0.4% (better)
Linux BenchmarkMergeCompilerFlags 202.900 ns/op -1.1 ns/op / -0.5% (better)
Linux BenchmarkMergeLinkerFlags 132.400 ns/op -3.1 ns/op / -2.3% (better)
Linux BenchmarkChannelBuffered 58.140 ns/op -0.3 ns/op / -0.5% (better)
Linux BenchmarkChannelHandoff 14355 ns/op -54 ns/op / -0.4% (better)
Linux BenchmarkDefer 48.050 ns/op -8.37 ns/op / -14.8% (better)
Linux BenchmarkDirectCall 1.165 ns/op -0.012 ns/op / -1.0% (better)
Linux BenchmarkGlobalRead 1.169 ns/op -0.004 ns/op / -0.3% (better)
Linux BenchmarkGlobalWrite 7.764 ns/op -0.103 ns/op / -1.3% (better)
Linux BenchmarkGoroutine 25496 ns/op -1468 ns/op / -5.4% (better)
Linux BenchmarkInterfaceCall 5.918 ns/op +0.041 ns/op / +0.7% (worse)
Linux BenchmarkRuntimeGetG 2.353 ns/op -0.713 ns/op / -23.3% (better)
macOS BenchmarkLookupPCRandom 10.750 ns/op -0.44 ns/op / -3.9% (better)
macOS BenchmarkMergeCompilerFlags 85.530 ns/op -1.42 ns/op / -1.6% (better)
macOS BenchmarkMergeLinkerFlags 58.420 ns/op +1.72 ns/op / +3.0% (worse)
macOS BenchmarkChannelBuffered 21.720 ns/op -1.09 ns/op / -4.8% (better)
macOS BenchmarkChannelHandoff 6825 ns/op -626 ns/op / -8.4% (better)
macOS BenchmarkDefer 27.260 ns/op -5.88 ns/op / -17.7% (better)
macOS BenchmarkDirectCall 0.866 ns/op -0.0584 ns/op / -6.3% (better)
macOS BenchmarkGlobalRead 0.872 ns/op -0.0245 ns/op / -2.7% (better)
macOS BenchmarkGlobalWrite 0.881 ns/op -0.0629 ns/op / -6.7% (better)
macOS BenchmarkGoroutine 30223 ns/op -744 ns/op / -2.4% (better)
macOS BenchmarkInterfaceCall 3.466 ns/op -0.415 ns/op / -10.7% (better)
macOS BenchmarkRuntimeGetG 1.729 ns/op -0.069 ns/op / -3.8% (better)
Windows MinGW BenchmarkLookupPCRandom 13.140 ns/op +0.07 ns/op / +0.5% (worse)
Windows MinGW BenchmarkMergeCompilerFlags 628 ns/op -37.7 ns/op / -5.7% (better)
Windows MinGW BenchmarkMergeLinkerFlags 550.500 ns/op -36.7 ns/op / -6.3% (better)
Windows MinGW BenchmarkChannelBuffered 34.260 ns/op +0.04 ns/op / +0.1% (worse)
Windows MinGW BenchmarkChannelHandoff 1286 ns/op +119 ns/op / +10.2% (worse)
Windows MinGW BenchmarkDefer 56.070 ns/op +0.17 ns/op / +0.3% (worse)
Windows MinGW BenchmarkDirectCall 1.547 ns/op -0.002 ns/op / -0.1% (better)
Windows MinGW BenchmarkGlobalRead 1.547 ns/op -0.004 ns/op / -0.3% (better)
Windows MinGW BenchmarkGlobalWrite 2.471 ns/op -0.006 ns/op / -0.2% (better)
Windows MinGW BenchmarkGoroutine 90853 ns/op -886 ns/op / -1.0% (better)
Windows MinGW BenchmarkInterfaceCall 8.375 ns/op 0 ns/op / +0.0%
Windows MinGW BenchmarkRuntimeGetG 2.482 ns/op -0.003 ns/op / -0.1% (better)
Windows MinGW 386 BenchmarkLookupPCRandom 26.680 ns/op +0.02 ns/op / +0.1% (worse)
Windows MinGW 386 BenchmarkMergeCompilerFlags 787.600 ns/op +76.2 ns/op / +10.7% (worse)
Windows MinGW 386 BenchmarkMergeLinkerFlags 702 ns/op +21.8 ns/op / +3.2% (worse)
Windows MinGW 386 BenchmarkChannelBuffered 41.980 ns/op -0.15 ns/op / -0.4% (better)
Windows MinGW 386 BenchmarkChannelHandoff 894.100 ns/op -43.3 ns/op / -4.6% (better)
Windows MinGW 386 BenchmarkDefer 49.380 ns/op +0.21 ns/op / +0.4% (worse)
Windows MinGW 386 BenchmarkDirectCall 1.550 ns/op -0.002 ns/op / -0.1% (better)
Windows MinGW 386 BenchmarkGlobalRead 1.552 ns/op +0.003 ns/op / +0.2% (worse)
Windows MinGW 386 BenchmarkGlobalWrite 7.779 ns/op +0.008 ns/op / +0.1% (worse)
Windows MinGW 386 BenchmarkGoroutine 102070 ns/op -2708 ns/op / -2.6% (better)
Windows MinGW 386 BenchmarkInterfaceCall 8.399 ns/op -0.011 ns/op / -0.1% (better)
Windows MinGW 386 BenchmarkRuntimeGetG 2.482 ns/op +0.002 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkLookupPCRandom 12.020 ns/op -0.1 ns/op / -0.8% (better)
Windows MinGW ARM64 BenchmarkMergeCompilerFlags 570.700 ns/op -9.4 ns/op / -1.6% (better)
Windows MinGW ARM64 BenchmarkMergeLinkerFlags 530.900 ns/op -11.9 ns/op / -2.2% (better)
Windows MinGW ARM64 BenchmarkChannelBuffered 38.450 ns/op +0.03 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkChannelHandoff 2991 ns/op -305 ns/op / -9.3% (better)
Windows MinGW ARM64 BenchmarkDefer 55.310 ns/op +0.27 ns/op / +0.5% (worse)
Windows MinGW ARM64 BenchmarkDirectCall 0.590 ns/op -0.0002 ns/op / -0.03391% (better)
Windows MinGW ARM64 BenchmarkGlobalRead 0.737 ns/op +0.0007 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkGlobalWrite 0.590 ns/op +0.0002 ns/op / +0.03393% (worse)
Windows MinGW ARM64 BenchmarkGoroutine 65669 ns/op +4177 ns/op / +6.8% (worse)
Windows MinGW ARM64 BenchmarkInterfaceCall 4.235 ns/op +0.001 ns/op / +0.02362% (worse)
Windows MinGW ARM64 BenchmarkRuntimeGetG 1.812 ns/op +0.043 ns/op / +2.4% (worse)
Windows MSVC BenchmarkLookupPCRandom 13.170 ns/op +0.01 ns/op / +0.1% (worse)
Windows MSVC BenchmarkMergeCompilerFlags 618.700 ns/op -4.1 ns/op / -0.7% (better)
Windows MSVC BenchmarkMergeLinkerFlags 536.300 ns/op -15.9 ns/op / -2.9% (better)
Windows MSVC BenchmarkChannelBuffered 34.120 ns/op -0.19 ns/op / -0.6% (better)
Windows MSVC BenchmarkChannelHandoff 1350 ns/op +56 ns/op / +4.3% (worse)
Windows MSVC BenchmarkDefer 54.610 ns/op +0.81 ns/op / +1.5% (worse)
Windows MSVC BenchmarkDirectCall 1.549 ns/op +0.002 ns/op / +0.1% (worse)
Windows MSVC BenchmarkGlobalRead 1.547 ns/op -0.002 ns/op / -0.1% (better)
Windows MSVC BenchmarkGlobalWrite 2.472 ns/op +0.002 ns/op / +0.1% (worse)
Windows MSVC BenchmarkGoroutine 86861 ns/op -233 ns/op / -0.3% (better)
Windows MSVC BenchmarkInterfaceCall 8.696 ns/op -3.434 ns/op / -28.3% (better)
Windows MSVC BenchmarkRuntimeGetG 2.173 ns/op +0.002 ns/op / +0.1% (worse)
Windows MSVC 386 BenchmarkLookupPCRandom 26.590 ns/op -0.08 ns/op / -0.3% (better)
Windows MSVC 386 BenchmarkMergeCompilerFlags 770.700 ns/op -40.6 ns/op / -5.0% (better)
Windows MSVC 386 BenchmarkMergeLinkerFlags 671.200 ns/op -34.9 ns/op / -4.9% (better)
Windows MSVC 386 BenchmarkChannelBuffered 41.790 ns/op +0.13 ns/op / +0.3% (worse)
Windows MSVC 386 BenchmarkChannelHandoff 1097 ns/op -34 ns/op / -3.0% (better)
Windows MSVC 386 BenchmarkDefer 53.770 ns/op +2.3 ns/op / +4.5% (worse)
Windows MSVC 386 BenchmarkDirectCall 1.551 ns/op +0.003 ns/op / +0.2% (worse)
Windows MSVC 386 BenchmarkGlobalRead 1.555 ns/op -0.008 ns/op / -0.5% (better)
Windows MSVC 386 BenchmarkGlobalWrite 7.791 ns/op -0.013 ns/op / -0.2% (better)
Windows MSVC 386 BenchmarkGoroutine 117302 ns/op +8832 ns/op / +8.1% (worse)
Windows MSVC 386 BenchmarkInterfaceCall 8.305 ns/op +0.039 ns/op / +0.5% (worse)
Windows MSVC 386 BenchmarkRuntimeGetG 2.484 ns/op +0.004 ns/op / +0.2% (worse)
Windows MSVC ARM64 BenchmarkLookupPCRandom 12.130 ns/op +0.08 ns/op / +0.7% (worse)
Windows MSVC ARM64 BenchmarkMergeCompilerFlags 587.500 ns/op +9 ns/op / +1.6% (worse)
Windows MSVC ARM64 BenchmarkMergeLinkerFlags 546 ns/op -7.9 ns/op / -1.4% (better)
Windows MSVC ARM64 BenchmarkChannelBuffered 39.050 ns/op +0.14 ns/op / +0.4% (worse)
Windows MSVC ARM64 BenchmarkChannelHandoff 3291 ns/op +397 ns/op / +13.7% (worse)
Windows MSVC ARM64 BenchmarkDefer 63.480 ns/op +0.44 ns/op / +0.7% (worse)
Windows MSVC ARM64 BenchmarkDirectCall 0.663 ns/op -0.0003 ns/op / -0.04519% (better)
Windows MSVC ARM64 BenchmarkGlobalRead 0.590 ns/op -0.0005 ns/op / -0.1% (better)
Windows MSVC ARM64 BenchmarkGlobalWrite 3.795 ns/op -0.003 ns/op / -0.1% (better)
Windows MSVC ARM64 BenchmarkGoroutine 60703 ns/op +1352 ns/op / +2.3% (worse)
Windows MSVC ARM64 BenchmarkInterfaceCall 4.164 ns/op 0 ns/op / +0.0%
Windows MSVC ARM64 BenchmarkRuntimeGetG 1.775 ns/op +0.006 ns/op / +0.3% (worse)
Timer runtime benchmarks
Platform Operation and runtime ns/op vs base
Linux AfterFuncZeroDelivery/Go 900.100 ns/op -28.3 ns/op / -3.0% (better)
Linux AfterFuncZeroDelivery/LLGo 37799 ns/op -2627 ns/op / -6.5% (better)
Linux CreateStop/Go 291.500 ns/op -5.5 ns/op / -1.9% (better)
Linux CreateStop/LLGo 1878 ns/op +63 ns/op / +3.5% (worse)
Linux RearmStopped/Go 114.600 ns/op -1.6 ns/op / -1.4% (better)
Linux RearmStopped/LLGo 1176 ns/op -118 ns/op / -9.1% (better)
Linux ResetActive/Go 67.420 ns/op -1.87 ns/op / -2.7% (better)
Linux ResetActive/LLGo 658.800 ns/op -54.1 ns/op / -7.6% (better)
Linux ResetHeap1024/Go 67.140 ns/op -0.05 ns/op / -0.1% (better)
Linux ResetHeap1024/LLGo 167.500 ns/op +1.8 ns/op / +1.1% (worse)
macOS AfterFuncZeroDelivery/Go 356.300 ns/op -41 ns/op / -10.3% (better)
macOS AfterFuncZeroDelivery/LLGo 45267 ns/op -891 ns/op / -1.9% (better)
macOS CreateStop/Go 114.600 ns/op -5.2 ns/op / -4.3% (better)
macOS CreateStop/LLGo 418.700 ns/op -71.6 ns/op / -14.6% (better)
macOS RearmStopped/Go 54.500 ns/op -0.69 ns/op / -1.3% (better)
macOS RearmStopped/LLGo 327.600 ns/op +9.4 ns/op / +3.0% (worse)
macOS ResetActive/Go 37.610 ns/op +1.54 ns/op / +4.3% (worse)
macOS ResetActive/LLGo 158.200 ns/op -7.2 ns/op / -4.4% (better)
macOS ResetHeap1024/Go 37.420 ns/op -1.19 ns/op / -3.1% (better)
macOS ResetHeap1024/LLGo 69 ns/op -6.99 ns/op / -9.2% (better)
Windows MinGW AfterFuncZeroDelivery/Go 573.100 ns/op +18.2 ns/op / +3.3% (worse)
Windows MinGW AfterFuncZeroDelivery/LLGo 189150 ns/op +1541 ns/op / +0.8% (worse)
Windows MinGW CreateStop/Go 112.800 ns/op -2.7 ns/op / -2.3% (better)
Windows MinGW CreateStop/LLGo 450.400 ns/op -36.8 ns/op / -7.6% (better)
Windows MinGW RearmStopped/Go 31.420 ns/op -0.11 ns/op / -0.3% (better)
Windows MinGW RearmStopped/LLGo 236.400 ns/op +6 ns/op / +2.6% (worse)
Windows MinGW ResetActive/Go 20.120 ns/op +0.03 ns/op / +0.1% (worse)
Windows MinGW ResetActive/LLGo 186.500 ns/op +6.6 ns/op / +3.7% (worse)
Windows MinGW ResetHeap1024/Go 20.400 ns/op -0.06 ns/op / -0.3% (better)
Windows MinGW ResetHeap1024/LLGo 122.400 ns/op +2.4 ns/op / +2.0% (worse)
Windows MinGW 386 AfterFuncZeroDelivery/Go 970.400 ns/op +3.5 ns/op / +0.4% (worse)
Windows MinGW 386 AfterFuncZeroDelivery/LLGo 202394 ns/op +2102 ns/op / +1.0% (worse)
Windows MinGW 386 CreateStop/Go 193.600 ns/op +1.8 ns/op / +0.9% (worse)
Windows MinGW 386 CreateStop/LLGo 494 ns/op +3.1 ns/op / +0.6% (worse)
Windows MinGW 386 RearmStopped/Go 64.130 ns/op +0.77 ns/op / +1.2% (worse)
Windows MinGW 386 RearmStopped/LLGo 335.200 ns/op -48.1 ns/op / -12.5% (better)
Windows MinGW 386 ResetActive/Go 39.310 ns/op +0.24 ns/op / +0.6% (worse)
Windows MinGW 386 ResetActive/LLGo 984 ns/op -51 ns/op / -4.9% (better)
Windows MinGW 386 ResetHeap1024/Go 39.670 ns/op -0.06 ns/op / -0.2% (better)
Windows MinGW 386 ResetHeap1024/LLGo 177.300 ns/op -2.2 ns/op / -1.2% (better)
Windows MinGW ARM64 AfterFuncZeroDelivery/Go 664.400 ns/op +9.2 ns/op / +1.4% (worse)
Windows MinGW ARM64 AfterFuncZeroDelivery/LLGo 151636 ns/op +818 ns/op / +0.5% (worse)
Windows MinGW ARM64 CreateStop/Go 206.100 ns/op +5.6 ns/op / +2.8% (worse)
Windows MinGW ARM64 CreateStop/LLGo 447.800 ns/op +11.7 ns/op / +2.7% (worse)
Windows MinGW ARM64 RearmStopped/Go 70.590 ns/op -0.01 ns/op / -0.01416% (better)
Windows MinGW ARM64 RearmStopped/LLGo 221.900 ns/op +1.8 ns/op / +0.8% (worse)
Windows MinGW ARM64 ResetActive/Go 31.060 ns/op -0.13 ns/op / -0.4% (better)
Windows MinGW ARM64 ResetActive/LLGo 123.700 ns/op +7.3 ns/op / +6.3% (worse)
Windows MinGW ARM64 ResetHeap1024/Go 31.090 ns/op -0.06 ns/op / -0.2% (better)
Windows MinGW ARM64 ResetHeap1024/LLGo 113.100 ns/op -0.2 ns/op / -0.2% (better)
Windows MSVC AfterFuncZeroDelivery/Go 561 ns/op +12.9 ns/op / +2.4% (worse)
Windows MSVC AfterFuncZeroDelivery/LLGo 169478 ns/op -609 ns/op / -0.4% (better)
Windows MSVC CreateStop/Go 115.300 ns/op +0.2 ns/op / +0.2% (worse)
Windows MSVC CreateStop/LLGo 433.500 ns/op -26.2 ns/op / -5.7% (better)
Windows MSVC RearmStopped/Go 31.490 ns/op +0.14 ns/op / +0.4% (worse)
Windows MSVC RearmStopped/LLGo 242.900 ns/op -29.5 ns/op / -10.8% (better)
Windows MSVC ResetActive/Go 20.120 ns/op +0.03 ns/op / +0.1% (worse)
Windows MSVC ResetActive/LLGo 176.500 ns/op -13.9 ns/op / -7.3% (better)
Windows MSVC ResetHeap1024/Go 20.500 ns/op -0.01 ns/op / -0.04876% (better)
Windows MSVC ResetHeap1024/LLGo 121.200 ns/op -2.3 ns/op / -1.9% (better)
Windows MSVC 386 AfterFuncZeroDelivery/Go 971.100 ns/op +13 ns/op / +1.4% (worse)
Windows MSVC 386 AfterFuncZeroDelivery/LLGo 211380 ns/op +998 ns/op / +0.5% (worse)
Windows MSVC 386 CreateStop/Go 194.300 ns/op -2.5 ns/op / -1.3% (better)
Windows MSVC 386 CreateStop/LLGo 499 ns/op -7.9 ns/op / -1.6% (better)
Windows MSVC 386 RearmStopped/Go 63.360 ns/op -0.21 ns/op / -0.3% (better)
Windows MSVC 386 RearmStopped/LLGo 321.400 ns/op +5.5 ns/op / +1.7% (worse)
Windows MSVC 386 ResetActive/Go 39.070 ns/op -0.05 ns/op / -0.1% (better)
Windows MSVC 386 ResetActive/LLGo 923.100 ns/op +638.2 ns/op / +224.0% (worse)
Windows MSVC 386 ResetHeap1024/Go 39.610 ns/op +0.21 ns/op / +0.5% (worse)
Windows MSVC 386 ResetHeap1024/LLGo 165.100 ns/op +0.9 ns/op / +0.5% (worse)
Windows MSVC ARM64 AfterFuncZeroDelivery/Go 661.400 ns/op -6.1 ns/op / -0.9% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/LLGo 151520 ns/op -5006 ns/op / -3.2% (better)
Windows MSVC ARM64 CreateStop/Go 201.600 ns/op +3.9 ns/op / +2.0% (worse)
Windows MSVC ARM64 CreateStop/LLGo 417.500 ns/op +1.5 ns/op / +0.4% (worse)
Windows MSVC ARM64 RearmStopped/Go 70.520 ns/op 0 ns/op / +0.0%
Windows MSVC ARM64 RearmStopped/LLGo 242.300 ns/op +7.8 ns/op / +3.3% (worse)
Windows MSVC ARM64 ResetActive/Go 30.980 ns/op -0.22 ns/op / -0.7% (better)
Windows MSVC ARM64 ResetActive/LLGo 124.500 ns/op -10.9 ns/op / -8.1% (better)
Windows MSVC ARM64 ResetHeap1024/Go 31.090 ns/op -0.1 ns/op / -0.3% (better)
Windows MSVC ARM64 ResetHeap1024/LLGo 119.100 ns/op +0.1 ns/op / +0.1% (worse)

Compared with 31adf2b5a5c4 measured in the same runner job.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

LLGo WebAssembly build benchmarks

9b001de13828 | workflow run | long-term charts

WebAssembly output sizes
Example, profile and compiler Wasm module vs base Generated JS glue vs base
cprintf/j32-emscripten/LLGo 149447 B 0 B / +0.0% 88541 B 0 B / +0.0%
cprintf/j32-goos-js/LLGo 148066 B 0 B / +0.0% 72985 B 0 B / +0.0%
cprintf/j64-emscripten-memory64/LLGo 136749 B 0 B / +0.0% 91712 B 0 B / +0.0%
cprintf/w32-goos-wasip1/LLGo 159710 B 0 B / +0.0% 0 B 0 B / 0.0%
cprintf/w32-wasi/LLGo 160318 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/j32-emscripten/LLGo 3004237 B 0 B / +0.0% 121077 B 0 B / +0.0%
fmtprintf/j32-goos-js/Go 2526852 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/j32-goos-js/LLGo 3100354 B 0 B / +0.0% 92140 B 0 B / +0.0%
fmtprintf/j64-emscripten-memory64/LLGo 2768379 B 0 B / +0.0% 125674 B 0 B / +0.0%
fmtprintf/w32-goos-wasip1/Go 2500019 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/w32-goos-wasip1/LLGo 2374992 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/w32-wasi/LLGo 2371681 B 0 B / +0.0% 0 B 0 B / 0.0%
j32-emscripten/LLGo 148964 B 0 B / +0.0% 88541 B 0 B / +0.0%
j32-goos-js/Go 1895533 B 0 B / +0.0% 0 B 0 B / 0.0%
j32-goos-js/LLGo 147816 B 0 B / +0.0% 72985 B 0 B / +0.0%
j64-emscripten-memory64/LLGo 136307 B 0 B / +0.0% 91712 B 0 B / +0.0%
reflectcall/j32-emscripten/LLGo 1531352 B 0 B / +0.0% 95417 B 0 B / +0.0%
reflectcall/j32-goos-js/Go 2191221 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/j32-goos-js/LLGo 1583425 B 0 B / +0.0% 79857 B 0 B / +0.0%
reflectcall/j64-emscripten-memory64/LLGo 1411631 B 0 B / +0.0% 99170 B 0 B / +0.0%
reflectcall/w32-goos-wasip1/Go 2205707 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/w32-goos-wasip1/LLGo 1309382 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/w32-wasi/LLGo 1306983 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-goos-wasip1/Go 1909947 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-goos-wasip1/LLGo 159384 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-wasi/LLGo 159992 B 0 B / +0.0% 0 B 0 B / 0.0%
LLGo WebAssembly build measurements
Example and profile Build vs base
j32-emscripten 7.889 s -41.81 ms / -0.5% (better)
j32-goos-js 7.832 s +215.9 ms / +2.8% (worse)
j64-emscripten-memory64 6.817 s +13.24 ms / +0.2% (worse)
reflectcall/w32-wasi 23.933 s -53.63 ms / -0.2% (better)
w32-goos-wasip1 4.912 s +19.2 ms / +0.4% (worse)
w32-wasi 4.665 s +159.9 ms / +3.5% (worse)

Compared with 057851875734 measured in the same runner job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant