Stream: git-wasmtime

Topic: wasmtime / PR #14753 Cache GuestProfiler's per-module sym...


view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 20:09):

andrewl6097 opened PR #14753 from andrewl6097:guest-profiler-cache-symbols to bytecodealliance:main:

Closes #14752

GuestProfiler::new rebuilds and re-demangles each module's symbol table on
every call, which costs milliseconds for large modules. This builds the table
the first time a profiler includes a module, keeps it on the Module, and
shares it through an Arc with every later profiler.

Changes:

Measurements, release build, x86_64 Linux, using the reproduction program from
the issue (median of 1000):

Functions Before After, first profiler After, later profilers
1,500 672 µs 695 µs 12.8 µs
10,000 4.60 ms 4.56 ms 79.9 µs

On a real 1.7 MB Rust module with about 1,500 functions, a later new() drops
from 2.36 ms to 16.3 µs (measured with this change applied to wasmtime 43.0.2).

The remaining per-profile cost still grows with the function count, about 8 ns
per function. I haven't looked into where it goes, and it isn't addressed here.

Checked locally: cargo test -p wasmtime --lib profiling; cargo fmt --check;
cargo clippy -p wasmtime --all-targets with no warnings; cargo check -p wasmtime --no-default-features with and without profiling, with and without
runtime. I couldn't run the CLI test suite (tests/all) locally.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 20:09):

andrewl6097 requested alexcrichton for a review on PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 20:09):

andrewl6097 requested wasmtime-core-reviewers for a review on PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 20:12):

andrewl6097 updated PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 20:55):

:memo: alexcrichton submitted PR review:

Thanks! Could the profiling_symbols cache be stored on the profiler itself rather than the Module though? Also for this I think it's ok to skip tests since it's just an internal refactor

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 21:06):

andrewl6097 commented on PR #14753:

I think that the issue there would be that Profilers are pretty short-lived things, AFAICT - there's one per time that you profile things, and so different invocations of the guest all get their own Profiler. wasmtime serve, for example, currently makes a new guest profiler on every instance that it creates. So absent a good deal more plumbing, like "create a new profiler using this old one" or "re-use a profiler", both of which then require API changes from consumers to get the benefit.

Happy to drop the test in either case.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 21:10):

andrewl6097 updated PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 21:10):

andrewl6097 edited PR #14753:

Closes #14752

GuestProfiler::new rebuilds and re-demangles each module's symbol table on
every call, which costs milliseconds for large modules. This builds the table
the first time a profiler includes a module, keeps it on the Module, and
shares it through an Arc with every later profiler.

Changes:

Measurements, release build, x86_64 Linux, using the reproduction program from
the issue (median of 1000):

Functions Before After, first profiler After, later profilers
1,500 672 µs 695 µs 12.8 µs
10,000 4.60 ms 4.56 ms 79.9 µs

On a real 1.7 MB Rust module with about 1,500 functions, a later new() drops
from 2.36 ms to 16.3 µs (measured with this change applied to wasmtime 43.0.2).

The remaining per-profile cost still grows with the function count, about 8 ns
per function. I haven't looked into where it goes, and it isn't addressed here.

Checked locally: the reproduction program from the issue; cargo fmt --check;
cargo clippy -p wasmtime --all-targets with no warnings; cargo check -p wasmtime --no-default-features with and without profiling, with and without
runtime. I couldn't run the CLI test suite (tests/all) locally.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2026 at 23:44):

github-actions[bot] added the label wasmtime:api on PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2026 at 14:40):

alexcrichton commented on PR #14753:

Ah that's a good point yeah. I'm personally a bit hesitant though to have the dependencies here worm their way into the data representation of modules because in theory profiling is a pretty orthogonal feature. The way we've solve this in the past is with a slightly different API design though -- could the string/module iterator passed to GuestProfiler::new be wrapped up in a new abstraction perhaps? Something like GuestProfilerModules and that can be the pre-computation/cache for the symbol table which is shared amongst a set of GuestProfilers?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2026 at 18:10):

andrewl6097 commented on PR #14753:

Ok - that's fair guidance. Let me noodle around on it for a bit here.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2026 at 18:40):

andrewl6097 updated PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2026 at 18:40):

andrewl6097 requested alexcrichton for a review on PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2026 at 18:40):

andrewl6097 requested wasmtime-default-reviewers for a review on PR #14753.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2026 at 18:49):

andrewl6097 updated PR #14753.


Last updated: Oct 31 2026 at 23:03 UTC