Skip to content

Profiling

Performance Monitor

NovaPhy includes an opt-in runtime performance monitor on World and FluidWorld. It captures aggregate per-phase timings in the C++ stepping pipeline and can export Chrome/Perfetto traces.

Basic Usage

import novaphy

world = novaphy.World(builder.build())
monitor = world.performance_monitor
monitor.enabled = True

for _ in range(120):
    world.step(1.0 / 120.0)

# Print phase statistics
slowest = sorted(monitor.phase_stats(), key=lambda s: s.avg_ms, reverse=True)
for stat in slowest[:5]:
    print(f"{stat.name}: avg={stat.avg_ms:.2f}ms, max={stat.max_ms:.2f}ms")

# Print per-frame metrics
for metric in monitor.last_frame_metrics():
    print(f"{metric.name}: {metric.value}")

Trace Export

For detailed per-frame analysis, enable trace mode and export to Chrome/Perfetto format:

monitor.trace_enabled = True

for _ in range(60):
    world.step(1.0 / 120.0)

monitor.write_trace_json("build/novaphy_trace.json")

Open the JSON file in:

Profiling Demo

NovaPhy includes a dedicated profiling demo:

# Rigid body profiling
python demos/demo_performance_monitor.py --scene rigid

# Fluid profiling
python demos/demo_performance_monitor.py --scene fluid --measured-steps 60

Best Practices

Disable visualization when profiling

Polyscope and Python-side rendering are NOT included in engine timings. Disable visualization when diagnosing engine performance.

  1. Use aggregate stats first to find the hot subsystem
  2. Use trace export for short, focused captures (60-120 steps)
  3. Profile with representative workloads (body count, collision density)
  4. Compare before/after when optimizing