Skip to content

Commit

Permalink
support Throughput::Elements
Browse files Browse the repository at this point in the history
Example output:
```
base     1.00    683.6±86.03µs  5.7 MElem/sec
```

- add CThroughput::elements to de/serialize the values
- replace Benchmark.bytes_per_second with a Throughput enum and adjust
- the output to print B/sec or Elem/sec accordingly

Fixes: BurntSushi#3
  • Loading branch information
tko committed Jun 11, 2020
1 parent 83040b4 commit 5cde4ae
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 22 deletions.
21 changes: 18 additions & 3 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub struct CBenchmark {
#[serde(rename_all = "PascalCase")]
pub struct CThroughput {
pub bytes: Option<u64>,
pub elements: Option<u64>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -165,15 +166,29 @@ impl Benchmark {
&self.info.full_id
}

pub fn bytes_per_second(&self) -> Option<f64> {
pub fn throughput(&self) -> Option<Throughput> {
const NANOS_PER_SECOND: f64 = 1_000_000_000.0;

self.info.throughput.as_ref().and_then(|t| t.bytes).map(|bytes| {
bytes as f64 * (NANOS_PER_SECOND / self.nanoseconds())
let scale = NANOS_PER_SECOND / self.nanoseconds();

self.info.throughput.as_ref().and_then(|t| {
if let Some(num) = t.bytes {
Some(Throughput::Bytes(num as f64 * scale))
} else if let Some(num) = t.elements {
Some(Throughput::Elements(num as f64 * scale))
} else {
None
}
})
}
}

#[derive(Clone, Copy, Debug)]
pub enum Throughput {
Bytes(f64),
Elements(f64),
}

impl BaseBenchmarks {
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<BaseBenchmarks> {
deserialize_json_path(path.as_ref())
Expand Down
43 changes: 24 additions & 19 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct Benchmark {
name: String,
nanoseconds: f64,
stddev: Option<f64>,
bytes_per_second: Option<f64>,
throughput: Option<data::Throughput>,
/// Whether this is the best benchmark in a group. This is only populated
/// when a `Comparison` is built.
best: bool,
Expand Down Expand Up @@ -74,7 +74,7 @@ impl Benchmark {
name: b.fullname().to_string(),
nanoseconds: b.nanoseconds(),
stddev: Some(b.stddev()),
bytes_per_second: b.bytes_per_second(),
throughput: b.throughput(),
best: false,
rank: 0.0,
}
Expand Down Expand Up @@ -134,7 +134,7 @@ pub fn columns<W: WriteColor>(
"\t {:<5.2} {:>14} {:>14}",
b.rank,
time(b.nanoseconds, b.stddev),
throughput(b.bytes_per_second),
throughput(b.throughput),
)?;
if b.best {
wtr.reset()?;
Expand Down Expand Up @@ -172,7 +172,7 @@ fn rows_one<W: WriteColor>(mut wtr: W, group: &Comparison) -> Result<()> {
b.name,
b.rank,
time(b.nanoseconds, b.stddev),
throughput(b.bytes_per_second),
throughput(b.throughput),
)?;
}
Ok(())
Expand Down Expand Up @@ -209,22 +209,27 @@ fn time(nanos: f64, stddev: Option<f64>) -> String {
}
}

fn throughput(bytes_per_second: Option<f64>) -> String {
const MIN_KB: f64 = (2 * (1 << 10) as u64) as f64;
const MIN_MB: f64 = (2 * (1 << 20) as u64) as f64;
const MIN_GB: f64 = (2 * (1 << 30) as u64) as f64;
fn throughput(throughput: Option<data::Throughput>) -> String {
use data::Throughput::*;
match throughput {
Some(Bytes(num)) => throughput_per(num, "B"),
Some(Elements(num)) => throughput_per(num, "Elem"),
_ => "? ?/sec".to_string(),
}
}

let per = match bytes_per_second {
None => return "? B/sec".to_string(),
Some(per) => per,
};
if per < MIN_KB {
format!("{} B/sec", per as u64)
} else if per < MIN_MB {
format!("{:.1} KB/sec", (per / (1 << 10) as f64))
} else if per < MIN_GB {
format!("{:.1} MB/sec", (per / (1 << 20) as f64))
fn throughput_per(per: f64, unit: &str) -> String {
const MIN_K: f64 = (2 * (1 << 10) as u64) as f64;
const MIN_M: f64 = (2 * (1 << 20) as u64) as f64;
const MIN_G: f64 = (2 * (1 << 30) as u64) as f64;

if per < MIN_K {
format!("{} {}/sec", per as u64, unit)
} else if per < MIN_M {
format!("{:.1} K{}/sec", (per / (1 << 10) as f64), unit)
} else if per < MIN_G {
format!("{:.1} M{}/sec", (per / (1 << 20) as f64), unit)
} else {
format!("{:.1} GB/sec", (per / (1 << 30) as f64))
format!("{:.1} G{}/sec", (per / (1 << 30) as f64), unit)
}
}

0 comments on commit 5cde4ae

Please sign in to comment.