use std::time::Duration;
#[derive(Debug, Default, Clone, Copy)]
pub struct PhaseTimings {
pub time_advance: Duration,
pub ephemeris: Duration,
pub mass_recompute: Duration,
pub integ_origins_pre: Duration,
pub kinematic_pre: Duration,
pub environment: Duration,
pub interactions: Duration,
pub integration: Duration,
pub integ_origins_post: Duration,
pub kinematic_post: Duration,
pub derived: Duration,
pub detached_subtrees: Duration,
pub steps: u64,
}
impl PhaseTimings {
pub fn total(&self) -> Duration {
self.time_advance
+ self.ephemeris
+ self.mass_recompute
+ self.integ_origins_pre
+ self.kinematic_pre
+ self.environment
+ self.interactions
+ self.integration
+ self.integ_origins_post
+ self.kinematic_post
+ self.derived
+ self.detached_subtrees
}
pub fn summary(&self) -> String {
let total = self.total();
let total_secs = total.as_secs_f64();
let steps = self.steps.max(1) as f64;
let row = |name: &str, d: Duration| {
let secs = d.as_secs_f64();
let pct = if total_secs > 0.0 {
100.0 * secs / total_secs
} else {
0.0
};
let per_step_us = 1e6 * secs / steps;
format!(" {name:<22} {secs:>9.3} s {pct:>6.2}% {per_step_us:>9.3} µs/step\n")
};
let mut out = String::new();
out.push_str(&format!(
"PhaseTimings: {} step(s), {:.3} s instrumented total\n",
self.steps, total_secs
));
out.push_str(&row("time_advance", self.time_advance));
out.push_str(&row("ephemeris", self.ephemeris));
out.push_str(&row("mass_recompute", self.mass_recompute));
out.push_str(&row("integ_origins_pre", self.integ_origins_pre));
out.push_str(&row("kinematic_pre", self.kinematic_pre));
out.push_str(&row("environment", self.environment));
out.push_str(&row("interactions", self.interactions));
out.push_str(&row("integration", self.integration));
out.push_str(&row("integ_origins_post", self.integ_origins_post));
out.push_str(&row("kinematic_post", self.kinematic_post));
out.push_str(&row("derived", self.derived));
out.push_str(&row("detached_subtrees", self.detached_subtrees));
out
}
}