Profiling Foundation
This document describes the standalone profiling foundation for Anemone.
Purpose
The profiling package can:
run a named scenario
measure total wall-clock time
capture basic execution metadata
persist a stable JSON artifact for each run
The profiling foundation is intentionally separate from the core search engine.
Constraints
This first version does not modify core search semantics and does not add timing or profiler hooks inside the search loop.
In particular, PR1 does not touch:
TreeExploration.step()AlgorithmNodeTreeManager
What Exists Today
anemone.profilingpackage undersrc/anemone/profiling/stable
RunResultJSON schema withschema_version = "1"run directory helpers
a standalone scenario runner
a minimal CLI
a tiny real
smokescenario using public Anemone APIslazy scenario loading so package import stays lightweight
optional external profiler modes:
none,cprofile,pyinstrumentwrapper-based component timing for evaluator and dynamics
component_summary.jsonartifact output when enabledcprofile.pstatsandcprofile_top.txtartifacts forcprofilepyinstrument.txtartifact whenpyinstrumentis requested and installedoptional GUI integrations for SnakeViz and gprof2dot call-graph generation
deterministic synthetic profiling scenarios:
cheap_evalexpensive_evalwide_treedeep_treereuse_heavy
repeatable profiling suites:
baselinequick
suite.jsonartifact output for repeated suite runs
What Is Still Out Of Scope
process-level profilers such as py-spy
viztracer integration
CI performance regression gates
flamegraph and speedscope-style timeline views
Running It
Preferred CLI:
python -m anemone.profiling.cli list-scenarios
python -m anemone.profiling.cli list-suites
python -m anemone.profiling.cli run --scenario smoke --output-dir profiling_runs
python -m anemone.profiling.cli run --scenario smoke --output-dir profiling_runs --profiler cprofile --component-summary
python -m anemone.profiling.cli run-suite --suite baseline --output-dir profiling_runs --repetitions 5 --component-summary
GUI launcher:
pip install -e .[gui]
python -m anemone.profiling.gui
Optional profiler-visualization extras:
pip install -e .[gui,profiling-viz]
Graph rendering for gprof2dot also requires the Graphviz dot executable to be
installed on the system.
Convenience runner entrypoint:
python -m anemone.profiling.runner --scenario smoke --output-dir profiling_runs
Output Layout
Each run creates a timestamped folder under the selected base directory:
profiling_runs/
2026-03-24T14-32-10_smoke/
run.json
component_summary.json
cprofile.pstats
cprofile_top.txt
If a run id collides, the storage helper appends a deterministic suffix such as
_2, _3, and so on.
The run.json artifact includes scenario metadata, execution metadata, top-level
wall time, run status, and placeholder artifact references for future tooling.
The recorded wall time tracks scenario execution itself and intentionally
excludes profiler artifact writing or profiler post-processing.
Suite runs create a separate suite-level directory with nested scenario runs:
profiling_runs/
2026-03-24T15-10-00_baseline_suite/
suite.json
scenario_runs/
2026-03-24T15-10-00_cheap_eval_rep1/
run.json
component_summary.json
2026-03-24T15-10-01_cheap_eval_rep2/
run.json
2026-03-24T15-10-05_wide_tree_rep1/
run.json
suite.json records:
suite metadata
requested repetition count
profiler and component-summary settings
per-scenario aggregate wall-time statistics across successful repetitions
per-repetition
run.jsonpaths and statuses
This keeps the suite artifact comparison-ready without requiring later tooling to re-scan directories.
GUI
PR4 adds a local Streamlit dashboard under anemone.profiling.gui.
The dashboard can:
launch scenarios and suites
browse existing runs and suites
display component timing breakdowns
show readable profiler text artifacts
expose SnakeViz launch commands for
cprofile.pstatsartifactsgenerate and display gprof2dot call graphs on demand
compare two runs or two suites
The GUI reads the existing profiling artifacts only. It does not add new profiling hooks or modify core search behavior.
When component summaries are enabled, the summary approximates framework overhead as:
residual_framework_wall_time_seconds
= total_run_wall_time_seconds - wrapped_component_wall_times
This residual is useful, but intentionally approximate.
Interactive cProfile visualization
For runs that include cprofile.pstats, the GUI exposes two optional tools:
SnakeViz for interactive browser-based inspection of the call stack
gprof2dot for caller/callee call-graph generation
Suggested setup:
pip install -e .[gui,profiling-viz]
python -m anemone.profiling.gui
When a run includes cprofile.pstats, the run page can:
show the exact
snakeviz /absolute/path/to/cprofile.pstatscommandgenerate DOT, SVG, or PNG call-graph artifacts under
profiler_visualizations/render generated SVG and PNG call graphs directly in the dashboard
Use the flat top-functions table when you want to answer:
which function is hot?
Use SnakeViz when you want to answer:
why is this function being reached?
which call path dominates cumulative time?
Use gprof2dot when you want to answer:
who calls the bottleneck?
which caller/callee relationships are shaping the hotspot?
gprof2dot thresholds control graph pruning, which makes it easier to simplify dense profiles before rendering a call graph image.
Scenario Roles
smokevalidates profiling plumbing and public API integration.cheap_evalkeeps evaluator work near zero so framework overhead is easier to see.expensive_evalmakes evaluator CPU cost dominant while keeping the tree shape similar.wide_treestresses broader opening pressure and legal-action generation.deep_treestresses deeper narrow traversal.reuse_heavystresses repeated shared-state patterns.