Skip to content

novaphy.PerformanceMonitor

Thread-local profiling utility. Wrap a step in with monitor.scoped(): ... to capture aggregate per-phase timings and (optionally) emit a Chrome / Perfetto trace. Outside the with block every C++ phase scope is a zero-cost no-op, so solver public APIs stay free of profiling parameters.

This mirrors Newton's EventTracer / event_scope pattern.

Attributes

Attribute Description
enabled Enable aggregate capture for future scoped frames.
trace_enabled Enable per-frame trace recording for write_trace_json. A scoped frame still captures when this is True even if enabled is False.
trace_frame_capacity Maximum number of recent profiled frames retained for trace export. Default: 120; setting a negative value clamps it to zero.
frame_count Read-only number of profiled frames captured since the last reset.
last_frame_total_ms Read-only wall-clock duration of the most recently completed profiled frame.

Methods

Method Description
scoped() Context manager. Capture the wrapped block.
reset() Clear aggregate statistics, last-frame metrics, and buffered trace data.
begin_frame() Manually start a profiled frame. Prefer scoped() unless manual lifecycle control is required.
end_frame() Finish and commit a frame opened by begin_frame().
record_metric(name, value) Record a numeric metric in the current profiled frame.
phase_stats() Aggregate stats list (PerformancePhaseStat).
last_frame_metrics() Per-frame metric list (PerformanceMetric).
write_trace_json(path) Write a Chrome / Perfetto trace JSON.

Example

import novaphy

monitor = novaphy.PerformanceMonitor()
monitor.enabled = True
monitor.trace_enabled = True

for _ in range(120):
    with monitor.scoped():
        solver.step(state, state, control, contacts, dt)

for stat in monitor.phase_stats():
    print(stat.name, stat.avg_ms)

monitor.write_trace_json("trace.json")

See Also