bevy/tools/spancmp/src/pretty.rs
Jakob Hellermann e71c4d2802 fix nightly clippy warnings (#6395)
# Objective

- fix new clippy lints before they get stable and break CI

## Solution

- run `clippy --fix` to auto-fix machine-applicable lints
- silence `clippy::should_implement_trait` for `fn HandleId::default<T: Asset>`

## Changes
- always prefer `format!("{inline}")` over `format!("{}", not_inline)`
- prefer `Box::default` (or `Box::<T>::default` if necessary) over `Box::new(T::default())`
2022-10-28 21:03:01 +00:00

235 lines
7.2 KiB
Rust

use bevy_utils::get_short_name;
use lazy_static::lazy_static;
use regex::Regex;
use termcolor::{Color, ColorSpec, StandardStream, WriteColor};
use crate::SpanStats;
pub fn print_spanstats(
stdout: &mut StandardStream,
reference: Option<&SpanStats>,
comparison: Option<&SpanStats>,
reference_only: bool,
) {
match (reference, comparison) {
(Some(reference), Some(comparison)) if !reference_only => {
let relative = comparison / reference;
print!("[count: {:8} | {:8} | ", reference.count, comparison.count);
print_relative(stdout, relative.count);
print!("] [min: ");
print_delta_time_us(reference.min);
print!(" | ");
print_delta_time_us(comparison.min);
print!(" | ");
print_relative(stdout, relative.min);
print!("] [avg: ");
print_delta_time_us(reference.avg);
print!(" | ");
print_delta_time_us(comparison.avg);
print!(" | ");
print_relative(stdout, relative.avg);
print!("] [max: ");
print_delta_time_us(reference.max);
print!(" | ");
print_delta_time_us(comparison.max);
print!(" | ");
print_relative(stdout, relative.max);
println!("]");
}
(Some(reference), None) if !reference_only => {
print!(
"[count: {:8} | | ] [min: ",
reference.count
);
print_delta_time_us(reference.min);
print!(" | | ] [avg: ");
print_delta_time_us(reference.avg);
print!(" | | ] [max: ");
print_delta_time_us(reference.max);
println!(" | | ]");
}
(None, Some(comparison)) => {
print!("[count: | {:8} | ", comparison.count);
print!("] [min: | ");
print_delta_time_us(comparison.min);
print!(" | ] [avg: | ");
print_delta_time_us(comparison.avg);
print!(" | ] [max: | ");
print_delta_time_us(comparison.max);
println!(" | ]");
}
(Some(reference), _) if reference_only => {
print!("[count: {:8}] [min: ", reference.count);
print_delta_time_us(reference.min);
print!("] [avg: ");
print_delta_time_us(reference.avg);
print!("] [max: ");
print_delta_time_us(reference.max);
println!("]");
}
_ => {}
}
}
const MARGIN_PERCENT: f32 = 2.0;
fn print_relative(stdout: &mut StandardStream, v: f32) {
let v_delta_percent = if v.is_nan() { 0.0 } else { (v - 1.0) * 100.0 };
set_fg(
stdout,
if v_delta_percent > MARGIN_PERCENT {
Color::Red
} else if v_delta_percent < -MARGIN_PERCENT {
Color::Green
} else {
Color::White
},
);
if v_delta_percent > MARGIN_PERCENT {
print!("+");
} else if v_delta_percent >= -MARGIN_PERCENT {
print!(" ");
} else {
print!("-");
}
print_base10f32_fixed_width(v_delta_percent.abs(), 1.0);
print!("%");
set_fg(stdout, Color::White);
}
// Try to print time values using 4 numeric digits, a decimal point, and the unit
const ONE_US_IN_SECONDS: f32 = 1e-6;
fn print_delta_time_us(dt_us: f32) {
print_base10f32_fixed_width(dt_us, ONE_US_IN_SECONDS);
print!("s");
}
fn print_base10f32_fixed_width(v: f32, v_scale: f32) {
Scale::from_value_and_scale(v, v_scale).print_with_scale(v, v_scale);
}
#[derive(Debug)]
pub struct Scale {
name: &'static str,
scale_factor: f32,
}
impl Scale {
pub const TERA: f32 = 1e12;
pub const GIGA: f32 = 1e9;
pub const MEGA: f32 = 1e6;
pub const KILO: f32 = 1e3;
pub const UNIT: f32 = 1e0;
pub const MILLI: f32 = 1e-3;
pub const MICRO: f32 = 1e-6;
pub const NANO: f32 = 1e-9;
pub const PICO: f32 = 1e-12;
pub fn from_value_and_scale(v: f32, v_scale: f32) -> Self {
assert!(v >= 0.0);
if v == 0.0 {
Self {
name: " ",
scale_factor: Self::UNIT,
}
} else if v * v_scale >= Self::TERA {
Self {
name: "T",
scale_factor: Self::TERA,
}
} else if v * v_scale >= Self::GIGA {
Self {
name: "G",
scale_factor: Self::GIGA,
}
} else if v * v_scale >= Self::MEGA {
Self {
name: "M",
scale_factor: Self::MEGA,
}
} else if v * v_scale >= Self::KILO {
Self {
name: "k",
scale_factor: Self::KILO,
}
} else if v * v_scale >= Self::UNIT {
Self {
name: " ",
scale_factor: Self::UNIT,
}
} else if v * v_scale >= Self::MILLI {
Self {
name: "m",
scale_factor: Self::MILLI,
}
} else if v * v_scale >= Self::MICRO {
Self {
name: "µ",
scale_factor: Self::MICRO,
}
} else if v * v_scale >= Self::NANO {
Self {
name: "n",
scale_factor: Self::NANO,
}
} else {
Self {
name: "p",
scale_factor: Self::PICO,
}
}
}
pub fn print(&self, v: f32) {
// NOTE: Hacks for rounding to decimal places to ensure precision is correct
let precision = if ((v * 10.0).round() / 10.0) >= 100.0 {
1
} else if ((v * 100.0).round() / 100.0) >= 10.0 {
2
} else {
3
};
print!("{v:5.precision$}{}", self.name);
}
pub fn print_with_scale(&self, v: f32, v_scale: f32) {
self.print(v * v_scale / self.scale_factor);
}
}
lazy_static! {
static ref SYSTEM_NAME: Regex = Regex::new(r#"system: name="([^"]+)""#).unwrap();
static ref SYSTEM_OVERHEAD: Regex = Regex::new(r#"system overhead: name="([^"]+)""#).unwrap();
static ref SYSTEM_COMMANDS: Regex = Regex::new(r#"system_commands: name="([^"]+)""#).unwrap();
}
pub fn simplify_name(name: &str) -> String {
if let Some(captures) = SYSTEM_NAME.captures(name) {
return format!(r#"system: name="{}""#, get_short_name(&captures[1]));
}
if let Some(captures) = SYSTEM_OVERHEAD.captures(name) {
return format!(
r#"system overhead: name="{}""#,
get_short_name(&captures[1])
);
}
if let Some(captures) = SYSTEM_COMMANDS.captures(name) {
return format!(
r#"system_commands: name="{}""#,
get_short_name(&captures[1])
);
}
name.to_string()
}
fn set_fg(stdout: &mut StandardStream, color: Color) {
stdout
.set_color(ColorSpec::new().set_fg(Some(color)))
.unwrap();
}
pub fn set_bold(stdout: &mut StandardStream, bold: bool) {
stdout.set_color(ColorSpec::new().set_bold(bold)).unwrap();
}