mirror of
https://github.com/bertptrs/tracing-mutex.git
synced 2025-12-27 13:30:32 +01:00
Implement minimal benchmarking of dependency tracking
This commit is contained in:
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -30,7 +30,8 @@ jobs:
|
|||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
args: --all-features
|
# --all-targets ensures that we also build the benchmarks and tests already.
|
||||||
|
args: --all-features --all-targets
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -7,13 +7,15 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Added generic support for wrapping mutexes that implement the traits provided by the
|
- Generic support for wrapping mutexes that implement the traits provided by the
|
||||||
[`lock_api`][lock_api] crate. This can be used for creating support for other mutex providers that
|
[`lock_api`][lock_api] crate. This can be used for creating support for other mutex providers that
|
||||||
implement it.
|
implement it.
|
||||||
|
|
||||||
- Added support for [`parking_lot`][parking_lot] mutexes. Support includes type aliases for all
|
- Support for [`parking_lot`][parking_lot] mutexes. Support includes type aliases for all
|
||||||
provided mutex types as well as a dedicated `Once` wrapper.
|
provided mutex types as well as a dedicated `Once` wrapper.
|
||||||
|
|
||||||
|
- Simple benchmark to track the rough performance penalty incurred by dependency tracking.
|
||||||
|
|
||||||
## [0.1.2] - 2021-05-27
|
## [0.1.2] - 2021-05-27
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -17,8 +17,13 @@ lock_api = { version = "0.4", optional = true }
|
|||||||
parking_lot = { version = "0.11", optional = true }
|
parking_lot = { version = "0.11", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
criterion = "0.3"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "mutex"
|
||||||
|
harness = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Feature names do not match crate names pending namespaced features.
|
# Feature names do not match crate names pending namespaced features.
|
||||||
lockapi = ["lock_api"]
|
lockapi = ["lock_api"]
|
||||||
|
|||||||
82
benches/mutex.rs
Normal file
82
benches/mutex.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use criterion::criterion_group;
|
||||||
|
use criterion::criterion_main;
|
||||||
|
use criterion::BenchmarkId;
|
||||||
|
use criterion::Criterion;
|
||||||
|
use criterion::Throughput;
|
||||||
|
use rand::prelude::*;
|
||||||
|
use tracing_mutex::stdsync::TracingMutex;
|
||||||
|
|
||||||
|
const SAMPLE_SIZES: [usize; 5] = [10, 30, 100, 300, 1000];
|
||||||
|
|
||||||
|
/// Reproducibly generate random combinations a, b where the index(a) < index(b)
|
||||||
|
///
|
||||||
|
/// All combinations are generated
|
||||||
|
fn generate_combinations<T>(options: &[Arc<T>]) -> Vec<(Arc<T>, Arc<T>)> {
|
||||||
|
let mut combinations = Vec::new();
|
||||||
|
|
||||||
|
for (i, first) in options.iter().enumerate() {
|
||||||
|
for second in options.iter().skip(i + 1) {
|
||||||
|
combinations.push((Arc::clone(first), Arc::clone(second)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rng = StdRng::seed_from_u64(42);
|
||||||
|
|
||||||
|
combinations.shuffle(&mut rng);
|
||||||
|
|
||||||
|
combinations
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Take two arbitrary mutexes, lock the first, lock the second while holding the first.
|
||||||
|
fn benchmark_baseline(c: &mut Criterion) {
|
||||||
|
let mut group = c.benchmark_group("baseline");
|
||||||
|
|
||||||
|
for nodes in SAMPLE_SIZES {
|
||||||
|
group.throughput(Throughput::Elements((nodes * (nodes - 1) / 2) as u64));
|
||||||
|
group.bench_with_input(BenchmarkId::from_parameter(nodes), &nodes, |b, &s| {
|
||||||
|
b.iter_batched(
|
||||||
|
|| {
|
||||||
|
let mutexes: Vec<_> = (0..s).map(|_| Arc::new(Mutex::new(()))).collect();
|
||||||
|
generate_combinations(&mutexes)
|
||||||
|
},
|
||||||
|
|combinations| {
|
||||||
|
for (first, second) in combinations {
|
||||||
|
let _first = first.lock();
|
||||||
|
let _second = second.lock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
criterion::BatchSize::SmallInput,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Same as [`benchmark_baseline`] but now while tracking dependencies.
|
||||||
|
fn benchmark_tracing_mutex(c: &mut Criterion) {
|
||||||
|
let mut group = c.benchmark_group("tracing_mutex");
|
||||||
|
|
||||||
|
for nodes in SAMPLE_SIZES {
|
||||||
|
group.throughput(Throughput::Elements((nodes * (nodes - 1) / 2) as u64));
|
||||||
|
group.bench_with_input(BenchmarkId::from_parameter(nodes), &nodes, |b, &s| {
|
||||||
|
b.iter_batched(
|
||||||
|
|| {
|
||||||
|
let mutexes: Vec<_> = (0..s).map(|_| Arc::new(TracingMutex::new(()))).collect();
|
||||||
|
generate_combinations(&mutexes)
|
||||||
|
},
|
||||||
|
|combinations| {
|
||||||
|
for (first, second) in combinations {
|
||||||
|
let _first = first.lock();
|
||||||
|
let _second = second.lock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
criterion::BatchSize::SmallInput,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(benches, benchmark_baseline, benchmark_tracing_mutex);
|
||||||
|
criterion_main!(benches);
|
||||||
Reference in New Issue
Block a user