Skip to content

Commit

Permalink
perf: small optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
camshaft committed Nov 22, 2024
1 parent 863b643 commit 8519e4b
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 65 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ jobs:
matrix:
rust: ${{ fromJson(needs.env.outputs.rust-versions) }}
os: [ubuntu-latest, macOS-latest, windows-latest]
include:
- rust: stable
os: ubuntu-latest
features: tracing,metrics
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -112,7 +116,7 @@ jobs:

- name: Run tests
run: |
cargo test
cargo test ${{ matrix.features && '--features' || '' }} ${{ matrix.features }}
miri:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ target
**/*.rs.bk
Cargo.lock
*.tar.gz
flamegraph.svg
perf.data*
13 changes: 9 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ members = [
]
resolver = "2"

[profile.release]
[profile.bench]
lto = true
codegen-units = 1
incremental = false

[profile.bench]
lto = true
codegen-units = 1
[profile.fuzz]
inherits = "dev"
opt-level = 3
incremental = false
codegen-units = 1

[profile.release-debug]
inherits = "dev"
opt-level = 3
6 changes: 4 additions & 2 deletions bach/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ edition = "2021"

[features]
coop = []
metrics = ["dep:metrics"]
net = []
tracing = ["dep:tracing"]

[dependencies]
arr_macro = "0.2"
Expand All @@ -19,10 +21,10 @@ event-listener-strategy = { version = "0.5.2", default-features = false }
futures-core = { version = "0.3", default-features = false }
intrusive-collections = "0.9"
pin-project-lite = "0.2"
metrics = "0.24"
metrics = { version = "0.24", optional = true }
rand = { version = "0.8", default-features = false }
rand_xoshiro = "0.6"
tracing = "0.1"
tracing = { version = "0.1", optional = true }

[dev-dependencies]
bolero = "0.11"
Expand Down
55 changes: 30 additions & 25 deletions bach/src/environment.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
use core::task::Poll;

pub mod default;

mod macrostep {
#[derive(Clone, Copy, Debug, Default)]
pub struct Macrostep {
pub tasks: usize,
pub ticks: u64,
}

impl Macrostep {
pub fn metrics(&self) {
measure!("tasks", self.tasks as u32);
measure!(
"advance",
crate::time::resolution::ticks_to_duration(self.ticks)
);
}
}
}

mod macrostep;
pub use macrostep::Macrostep;

pub trait Environment {
fn enter<F: FnOnce() -> O, O>(&self, f: F) -> O;

fn run<Tasks, F>(&mut self, tasks: Tasks) -> Poll<()>
fn run<Tasks, R>(&mut self, tasks: Tasks) -> Poll<()>
where
Tasks: IntoIterator<Item = F>,
F: 'static + FnOnce() -> Poll<()> + Send;
Tasks: IntoIterator<Item = R>,
R: Runnable;

fn on_macrostep(&mut self, macrostep: Macrostep) -> Macrostep {
macrostep
Expand All @@ -38,9 +20,32 @@ pub trait Environment {
where
F: 'static + FnOnce() + Send,
{
let _ = self.run(Some(move || {
close();
struct Close<F>(F);

impl<F> Runnable for Close<F>
where
F: 'static + FnOnce() + Send,
{
fn run(self) -> Poll<()> {
(self.0)();
Poll::Ready(())
}
}

let _ = self.run(Some(Close(close)));
}
}

pub trait Runnable: 'static + Send {
fn run(self) -> Poll<()>;
}

impl Runnable for async_task::Runnable {
fn run(self) -> Poll<()> {
if self.run() {
Poll::Pending
} else {
Poll::Ready(())
}));
}
}
}
10 changes: 5 additions & 5 deletions bach/src/environment/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{environment::Environment as _, executor, rand, time::scheduler};
use core::task::Poll;
use std::time::Duration;

use super::Macrostep;
use super::{Macrostep, Runnable};

pub struct Runtime {
inner: executor::Executor<Environment>,
Expand Down Expand Up @@ -90,10 +90,10 @@ impl super::Environment for Environment {
self.handle.enter(|| self.time.enter(|| self.rand.enter(f)))
}

fn run<Tasks, F>(&mut self, tasks: Tasks) -> Poll<()>
fn run<Tasks, R>(&mut self, tasks: Tasks) -> Poll<()>
where
Tasks: IntoIterator<Item = F>,
F: 'static + FnOnce() -> Poll<()> + Send,
Tasks: IntoIterator<Item = R>,
R: Runnable,
{
let mut is_ready = true;

Expand All @@ -107,7 +107,7 @@ impl super::Environment for Environment {
// TODO run network here

for task in tasks {
is_ready &= task().is_ready();
is_ready &= task.run().is_ready();
}
})
})
Expand Down
15 changes: 15 additions & 0 deletions bach/src/environment/macrostep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#[derive(Clone, Copy, Debug, Default)]
pub struct Macrostep {
pub tasks: usize,
pub ticks: u64,
}

impl Macrostep {
pub fn metrics(&self) {
measure!("tasks", self.tasks as u32);
measure!(
"advance",
crate::time::resolution::ticks_to_duration(self.ticks)
);
}
}
36 changes: 20 additions & 16 deletions bach/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,21 @@ impl<E: Environment> Executor<E> {
return Poll::Ready(0);
}

struct Iter<'a> {
queue: &'a Queue,
}

impl<'a> IntoIterator for Iter<'a> {
type Item = Runnable;
type IntoIter = std::collections::vec_deque::IntoIter<Runnable>;

fn into_iter(self) -> Self::IntoIter {
self.queue.drain().into_iter()
}
}

// make the drain lazy so the environment can be entered
let tasks = Some(&self.queue)
.into_iter()
.flat_map(|v| v.drain())
.map(|runnable| {
move || {
if runnable.run() {
Poll::Pending
} else {
Poll::Ready(())
}
}
});
let tasks = Iter { queue: &self.queue };

if self.environment.run(tasks).is_ready() {
Poll::Ready(task_count)
Expand Down Expand Up @@ -250,6 +252,8 @@ impl Handle {

#[cfg(test)]
pub(crate) mod tests {
use crate::environment::Runnable;

use super::*;

pub fn executor() -> Executor<Env> {
Expand All @@ -264,14 +268,14 @@ pub(crate) mod tests {
f()
}

fn run<Tasks, F>(&mut self, tasks: Tasks) -> Poll<()>
fn run<Tasks, R>(&mut self, tasks: Tasks) -> Poll<()>
where
Tasks: IntoIterator<Item = F>,
F: 'static + FnOnce() -> Poll<()> + Send,
Tasks: IntoIterator<Item = R>,
R: Runnable,
{
let mut is_ready = true;
for task in tasks {
is_ready &= task().is_ready();
is_ready &= task.run().is_ready();
}
if is_ready {
Poll::Ready(())
Expand Down
3 changes: 2 additions & 1 deletion bach/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::tracing::info_span;
use core::{
fmt,
future::Future,
Expand Down Expand Up @@ -110,7 +111,7 @@ where
let this = self.project();
let inner = this.inner;
let group = this.group;
let span = tracing::info_span!("group", %group);
let span = info_span!("group", %group);
scope::with(*group, || span.in_scope(|| Future::poll(inner, cx)))
}
}
2 changes: 2 additions & 0 deletions bach/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
extern crate alloc;

#[macro_use]
mod tracing;
#[macro_use]
pub mod metrics;

Expand Down
37 changes: 34 additions & 3 deletions bach/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,55 @@
#[doc(hidden)]
#[cfg(feature = "metrics")]
pub mod macro_support {
pub use ::metrics::*;
pub use ::tracing::trace;
}

#[macro_export]
#[cfg(feature = "metrics")]
macro_rules! measure {
($name:literal, $value:expr $(, $key:literal = $v:expr)* $(,)?) => {
$crate::metrics::macro_support::trace!(measure = %$name, value = ?$value $(, $key = %$v)*);
$crate::tracing::trace!(measure = %$name, value = ?$value $(, $key = %$v)*);
$crate::metrics::macro_support::histogram!($name $(, $key => $v)*).record($value);
};
}

#[macro_export]
#[cfg(not(feature = "metrics"))]
macro_rules! measure {
($name:literal, $value:expr $(, $key:literal = $v:expr)* $(,)?) => {
let _ = $name;
let _ = $value;
$(
let _ = $key;
let _ = $v;
)*
};
}

#[macro_export]
#[cfg(feature = "metrics")]
macro_rules! count {
($name:literal $(, $key:literal = $v:expr)* $(,)?) => {
$crate::count!($name, 1 $(, $key = $v)*);
};
($name:literal, $value:expr $(, $key:literal = $v:expr)* $(,)?) => {
$crate::metrics::macro_support::trace!(count = %$name, value = %$value $(, $key = %$v)*);
$crate::tracing::trace!(count = %$name, value = %$value $(, $key = %$v)*);
$crate::metrics::macro_support::counter!($name $(, $key => $v)*).increment($value);
};
}

#[macro_export]
#[cfg(not(feature = "metrics"))]
macro_rules! count {
($name:literal $(, $key:literal = $v:expr)* $(,)?) => {
$crate::count!($name, 1 $(, $key = $v)*);
};
($name:literal, $value:expr $(, $key:literal = $v:expr)* $(,)?) => {
let _ = $name;
let _ = $value;
$(
let _ = $key;
let _ = $v;
)*
}
}
2 changes: 1 addition & 1 deletion bach/src/sync/queue/latent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use super::{CloseError, PopError, PushError};
use crate::{
ext::*,
time::{Duration, Instant},
tracing::{debug_span, Instrument},
};
use std::{marker::PhantomData, task::Context};
use tracing::{debug_span, Instrument};

pub trait Latency<T> {
fn for_value(&self, value: &T) -> Duration;
Expand Down
6 changes: 4 additions & 2 deletions bach/src/sync/queue/span.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use super::{CloseError, PopError, PushError};
use crate::tracing::{info_span, Span};
use core::{fmt, ops};
use std::task::Context;

pub struct Queue<Q> {
#[cfg_attr(not(feature = "tracing"), allow(dead_code))]
name: &'static str,
inner: Q,
}
Expand Down Expand Up @@ -35,8 +37,8 @@ impl<Q> Queue<Q> {
Self { name, inner }
}

fn span(&self) -> tracing::Span {
tracing::info_span!("queue", queue = %self.name)
fn span(&self) -> Span {
info_span!("queue", queue = %self.name)
}
}

Expand Down
Loading

0 comments on commit 8519e4b

Please sign in to comment.