Skip to content

Commit

Permalink
rune: Add more benches
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Nov 3, 2024
1 parent 6cbd6be commit 54ea293
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 34 deletions.
31 changes: 31 additions & 0 deletions crates/rune/benches/primes.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const MAX_NUMBER_TO_CHECK = 10_000;

#[bench]
pub fn primes(b) {
b.iter(
|| {
let prime_mask = [];

prime_mask.resize(MAX_NUMBER_TO_CHECK, true);

prime_mask[0] = false;
prime_mask[1] = false;

let total_primes_found = 0;

for p in 2..MAX_NUMBER_TO_CHECK {
if prime_mask[p] {
total_primes_found += 1;
let i = 2 * p;

while i < MAX_NUMBER_TO_CHECK {
prime_mask[i] = false;
i += p;
}
}
}

total_primes_found
},
);
}
76 changes: 56 additions & 20 deletions crates/rune/src/cli/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use crate::modules::capture_io::CaptureIo;
use crate::modules::test::Bencher;
use crate::runtime::{Function, Unit, Value};
use crate::support::Result;
use crate::{Context, Hash, Item, ItemBuf, Sources, Vm};
use crate::{Context, Hash, ItemBuf, Sources, Vm};

use super::{Color, Stream};

mod cli {
use std::path::PathBuf;
Expand All @@ -23,7 +25,7 @@ mod cli {
#[command(rename_all = "kebab-case")]
pub(crate) struct Flags {
/// Rounds of warmup to perform
#[arg(long, default_value = "100")]
#[arg(long, default_value = "10")]
pub(super) warmup: u32,
/// Iterations to run of the benchmark
#[arg(long, default_value = "100")]
Expand Down Expand Up @@ -74,7 +76,9 @@ pub(super) async fn run(
return Ok(ExitCode::Success);
}

writeln!(io.stdout, "Found {} benches...", fns.len())?;
io.section("Benching", Stream::Stdout, Color::Highlight)?
.append(format_args!(" Found {} benches", fns.len()))?
.close()?;

let mut any_error = false;

Expand All @@ -100,7 +104,16 @@ pub(super) async fn run(
let multiple = fns.len() > 1;

for (i, f) in fns.iter().enumerate() {
if let Err(e) = bench_fn(io, i, item, args, f, multiple) {
let out;

let item: &dyn fmt::Display = if multiple {
out = DisplayHash(item, i);
&out
} else {
&item
};

if let Err(e) = bench_fn(io, item, args, f) {
writeln!(io.stdout, "{}: Error in bench iteration: {}", item, e)?;

if let Some(capture_io) = capture_io {
Expand All @@ -121,23 +134,51 @@ pub(super) async fn run(
}
}

fn bench_fn(
io: &mut Io<'_>,
i: usize,
item: &Item,
args: &Flags,
f: &Function,
multiple: bool,
) -> Result<()> {
for _ in 0..args.warmup {
struct DisplayHash<A, B>(A, B);

impl<A, B> fmt::Display for DisplayHash<A, B>
where
A: fmt::Display,
B: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self(a, b) = self;
write!(f, "{a}#{b}")
}
}

fn bench_fn(io: &mut Io<'_>, item: &dyn fmt::Display, args: &Flags, f: &Function) -> Result<()> {
let mut section = io.section("Warming up", Stream::Stdout, Color::Ignore)?;
section.append(format_args!(" {item} ({} iterations): ", args.warmup))?;

let step = (args.warmup / 10).max(1);

for n in 0..args.warmup {
if n % step == 0 {
section.append(".")?;
section.flush()?;
}

let value = f.call::<Value>(()).into_result()?;
drop(hint::black_box(value));
}

section.close()?;

let iterations = usize::try_from(args.iter).expect("iterations out of bounds");
let mut collected = Vec::try_with_capacity(iterations)?;

for _ in 0..args.iter {
let step = (args.iter / 10).max(1);

let mut section = io.section("Running", Stream::Stdout, Color::Highlight)?;
section.append(format_args!(" {item} ({} iterations): ", args.iter))?;

for n in 0..args.iter {
if n % step == 0 {
section.append(".")?;
section.flush()?;
}

let start = Instant::now();
let value = f.call::<Value>(()).into_result()?;
let duration = Instant::now().duration_since(start);
Expand All @@ -163,12 +204,7 @@ fn bench_fn(
iterations,
};

if multiple {
writeln!(io.stdout, "bench {}#{}: {}", item, i, format)?;
} else {
writeln!(io.stdout, "bench {}: {}", item, format)?;
}

section.passed(format_args!(" {format}"))?.close()?;
Ok(())
}

Expand Down
34 changes: 24 additions & 10 deletions crates/rune/src/cli/out.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,27 +130,41 @@ pub(super) struct Section<'a> {
}

impl Section<'_> {
pub(super) fn append(&mut self, text: impl fmt::Display) -> io::Result<()> {
write!(self.io, "{text}")
pub(super) fn append(&mut self, text: impl fmt::Display) -> io::Result<&mut Self> {
write!(self.io, "{text}")?;
Ok(self)
}

/// Flush the current section.
pub(super) fn flush(&mut self) -> io::Result<&mut Self> {
self.io.flush()?;
Ok(self)
}

pub(super) fn append_with(&mut self, text: impl fmt::Display, color: Color) -> io::Result<()> {
pub(super) fn append_with(
&mut self,
text: impl fmt::Display,
color: Color,
) -> io::Result<&mut Self> {
self.io.set_color(color.find(self.colors))?;
write!(self.io, "{text}")?;
self.io.reset()?;
Ok(())
Ok(self)
}

pub(super) fn error(&mut self, text: impl fmt::Display) -> io::Result<()> {
self.append_with(text, Color::Error)
pub(super) fn error(&mut self, text: impl fmt::Display) -> io::Result<&mut Self> {
self.append_with(text, Color::Error)?;
Ok(self)
}

pub(super) fn passed(&mut self, text: impl fmt::Display) -> io::Result<()> {
self.append_with(text, Color::Passed)
pub(super) fn passed(&mut self, text: impl fmt::Display) -> io::Result<&mut Self> {
self.append_with(text, Color::Passed)?;
Ok(self)
}

pub(super) fn close(self) -> io::Result<()> {
writeln!(self.io)
pub(super) fn close(&mut self) -> io::Result<()> {
writeln!(self.io)?;
Ok(())
}
}

Expand Down
18 changes: 14 additions & 4 deletions crates/rune/tests/variants.rn
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@

/// Tests that different variants of the same enum can be compared to each other
/// See: https://github.com/rune-rs/rune/pull/215
#[test]
fn assert_variant_comparisons() {
enum Units { A, B }
enum Units {
A,
B,
}

assert_ne!(Units::A, Units::B);
assert_eq!(Units::A, Units::A);

enum Mixed1 { A(a), B }
enum Mixed1 {
A(a),
B,
}

assert_ne!(Mixed1::A(10), Mixed1::B);
assert_eq!(Mixed1::A(10), Mixed1::A(10));

enum Mixed2 { A { a }, B }
enum Mixed2 {
A {
a,
},
B,
}

assert_ne!(Mixed2::A { a: 10 }, Mixed2::B);
assert_eq!(Mixed2::A { a: 10 }, Mixed2::A { a: 10 });
Expand Down

0 comments on commit 54ea293

Please sign in to comment.