Skip to content

tyc profile

tyc profile [PATH] [--out DIR]

Runs the normal tyc build pipeline, then post-processes every emitted .py so each top-level function records its call count and cumulative wall-clock time. When the instrumented program exits, an atexit hook writes the counters to typhon-profile.json. That file feeds [strictness] pgo-memoise, which promotes hot pure functions to @functools.cache on the next build.

tyc profile does not run the program — it only produces the instrumented build. You run the emitted entry point yourself with a representative workload.

Examples

Terminal window
tyc profile # instrumented build → build/
python build/main.py --bench # run it; typhon-profile.json is written on exit
tyc build # with pgo-memoise = true, hot pure fns are now cached
tyc profile --out dist/ # instrument into dist/ instead of the configured out dir
TYPHON_PROFILE_OUT=/tmp/p.json python build/main.py # write the profile somewhere else

Run the instrumented program from the project root: the profile is written to the process’s working directory (or to TYPHON_PROFILE_OUT), and tyc build reads typhon-profile.json from the directory that holds typhon.toml.

What the profile contains

A JSON object keyed by <module>.<qualname>, exactly as Python’s fn.__module__ and fn.__qualname__ report them:

{
"__main__.parse_port": {
"calls": 12483,
"total_seconds": 0.0084
},
"users.find_user": {
"calls": 4521,
"total_seconds": 0.1249
}
}

The entry module runs as __main__, so its functions are recorded as __main__.<fn>; every other module is keyed by its dotted module name (pkg.sub.helpers.<fn>).

Using the profile

Enable PGO in typhon.toml (or set [optimise] level = 1, which flips the default):

[strictness]
pgo-memoise = true
pgo-min-calls = 100 # threshold; default 100

On the next tyc build, every function that passes the purity analysis and whose recorded call count meets pgo-min-calls is promoted to @functools.cache — even if you didn’t write @memo. This complements auto-memoise (which caches every pure function regardless of hot-ness). A function already carrying @memo is never double-decorated.

The match is per module: a users.find_user sample only ever promotes find_user in src/users.ty, never a same-named function elsewhere. For the entry module both the __main__.<fn> spelling the profiler writes and the main.<fn> spelling are accepted, so the round trip works for src/main.ty out of the box. A bare <fn> key with no module qualifier matches by name, as a fallback for profiles produced by other tools.

Missing profile file

Not an error — and not a warning either; PGO is best-effort. With pgo-memoise = true and no typhon-profile.json, tyc build simply promotes nothing and falls through to the explicit @memo / auto-memoise paths.

  1. Write a “representative” entry point (e.g. a benchmark or a CLI invocation that exercises hot paths).
  2. tyc profile, then run the instrumented program from the project root.
  3. Commit typhon-profile.json (or generate it in CI).
  4. tyc build with pgo-memoise = true.

PGO is purely additive — functions promoted by PGO behave the same as ones you marked @memo manually. They get cached; their purity is verified at build time.

What’s profiled

Every top-level def / async def in the project’s emitted modules — not class or impl methods, not closures inside other functions, and not the generated typhon_runtime/ helpers. Broadening the surface is a follow-up.

Flags

FlagDefaultEffect
PATH.Project directory.
--out DIR (-o)[project] outOutput directory for the instrumented build, forwarded to tyc build.

Where the profile lands is controlled at run time by the TYPHON_PROFILE_OUT environment variable (default typhon-profile.json in the working directory), not by a tyc profile flag.

Where next