simvx.core.debug.profiler

Frame profiler with ring-buffer timing and per-node hotspot tracking.

Module Contents

Classes

FrameProfiler

Ring-buffer frame timer + per-node hotspot sampler.

Data

API

simvx.core.debug.profiler.log

‘getLogger(…)’

simvx.core.debug.profiler.__all__

[‘FrameProfiler’]

class simvx.core.debug.profiler.FrameProfiler[source]

Ring-buffer frame timer + per-node hotspot sampler.

Three layers of data:

  • Phases — named sections (process, physics, draw…). begin(phase) / end(phase) time code blocks; end_frame() commits the per-phase timings into the ring buffer.

  • Countscount_nodes(tree) walks the tree once per frame to populate node_count / control_count. Renderer stats (mesh count, draw calls) can be stored directly.

  • Hotspotssample_node(path, ms) accumulates per-node process / physics time. hotspots(n) returns the top-N by EMA-smoothed time.

enabled=False is a cheap guard; begin/end/sample_node return immediately so the instrumentation has near-zero cost when disabled.

Initialization

begin(phase: str)[source]
end(phase: str)[source]
end_frame()[source]
count_nodes(tree)[source]

Traverse tree and count nodes/controls. Call once per frame.

set_renderer_counts(*, meshes: int = 0, draw_calls: int = 0) None[source]

Record renderer-side counters (set by the graphics backend).

sample_node(path: str, phase: str, ms: float) None[source]

Record that path spent ms milliseconds in phase.

phase is one of "process" or "physics". Samples accumulate across the frame; end_frame() folds them into the EMA.

hotspots(n: int = 10) list[tuple[str, float]][source]

Return the top-N node paths by smoothed per-frame time (ms).

record_gpu_phase(name: str, ms: float) None[source]

Append a per-pass GPU timing sample (in milliseconds).

Producers (the editor’s per-frame tick) copy engine.gpu_phase_times into the profiler one entry at a time. Each label keeps its own ring buffer so passes that are conditionally enabled don’t pollute the history of unrelated passes.

gpu_phase_history_for(name: str, count: int = _GPU_HISTORY_SIZE) list[float][source]

Recent GPU samples for name (oldest first).

gpu_phase_latest() dict[str, float][source]

Latest published GPU sample per label (label -> ms).

clear_gpu_phases() None[source]

Drop all GPU history. Used by callers when the renderer goes away.

memory_mb() float[source]

Return the current process RSS in megabytes, or 0.0 if unavailable.

Uses /proc/self/statm on Linux, resource.getrusage elsewhere. Returns 0.0 on Windows (no cheap built-in available).

property fps: float[source]
property frame_time_ms: float[source]
property node_count: int[source]
property control_count: int[source]
property mesh_count: int[source]
property draw_call_count: int[source]
property last_frame: dict[str, float][source]

Phase timings from the most recent completed frame.

property sample_count: int[source]

Total frames recorded (saturates at ring capacity).

phase_avg_ms(phase: str, count: int = 60) float[source]

Average time for a phase over the last count frames.

phase_max_ms(phase: str, count: int = 60) float[source]

Maximum time for a phase over the last count frames.

frame_times(count: int = 120) list[float][source]

Recent total phase times for graph rendering (oldest first).

phase_history(phase: str, count: int = 120) list[float][source]

Per-frame time for phase over recent frames (oldest first).

reset() None[source]

Discard all recorded samples and hotspot averages.