Skip to content

Summarize only Scene-reachable callables to cut the cold path #11

Description

@Hosi121

Goal

Summarize only the callables an analyzed Scene can reach, instead of every callable in the project. This is the one remaining change that could move the cold path from seconds to under a second.

Measurements

On a 393-file / 161,869-line project (the Manim Community fork), release build, 16 logical cores:

phase cost
decode + tokenize + parse 1.00 s (parallelized in #6)
building method summaries 4.07 s of the 4.9 s total
everything else remainder

Inside that phase, instrumentation showed the scheduling is not the problem, which is worth recording so nobody re-investigates it:

  • 5,629 components, 17 rounds; the dependency scan costs 3 ms total
  • round sizes [2445, 938, 544, 428, 234, 326, 184, 143, 104, 97, 65, 58, 24, 3, 3, 1, 1] — the tail rounds that parallelize worst cost 22 ms of 4,067 ms
  • the sequential recursive-component pass costs 448 ms (~11%), the only other candidate

The cost is simply 5,629 callables at ~9 ms of CPU each. Thread scaling is 39.1 → 20.3 → 10.5 → 6.6 → 5.5 s at 1/2/4/8/16 threads; the knee at 8→16 is this machine's P-core/E-core split, so parallelism is close to exhausted.

Hypothesis

Summaries exist so the lifecycle interpreter can inline a call it meets while executing a Scene. A callable that no analyzed Scene reaches, transitively, therefore has a summary that is never read. In a library project most definitions are exactly that: the fork's manim/ package defines thousands of callables and contains almost no Scene subclasses.

If the reachable set is, say, 800 of 5,629, the dominant phase drops by roughly the same ratio and the cold run lands in the 1-second range.

Why this is not a quick patch

It can change results, which makes it a correctness change wearing a performance costume:

  • some rules may read summaries for callables outside any Scene's reach — that has to be established from the code, not assumed
  • the coverage report and static-facts may need the full table even when check does not
  • roots are not just Scene.construct: setup/teardown hooks, MRO-composed base methods, and callbacks registered from a Scene all count
  • a first attempt at computing the reachable set during this investigation returned 0, i.e. the root detection was wrong — evidence that the root set is the hard part, not the traversal

Suggested order

  1. Compute the reachable set and log its size only, changing no behavior. Land that, and get the real ratio for several projects. If the ratio is not large, close this issue.
  2. Establish which consumers need summaries for unreachable callables, from the code.
  3. Only then make the table demand-driven, gated so the full table is still built for the consumers that need it.
  4. Verify byte-identical diagnostics across all four corpora used in fix: make manim-lint safe to point at code we did not write, readable when it reports, and faster cold #6 before and after.

Acceptance

  • The reachable-set ratio is measured and recorded in docs/research/
  • Diagnostics are byte-identical on the fast-manim, ManimML, manim-slides, and manim-physics corpora
  • Cold time on the 393-file corpus is reported before and after

Related

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions