Upgrade deps
This commit is contained in:
parent
7c73d32ffa
commit
09055da93c
5 changed files with 32 additions and 22 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "median-accumulator"
|
name = "median-accumulator"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["tuxmain <tuxmain@zettascript.org>"]
|
authors = ["tuxmain <tuxmain@zettascript.org>"]
|
||||||
license = "AGPL-3.0-only"
|
license = "AGPL-3.0-only"
|
||||||
repository = "https://git.txmn.tk/tuxmain/median-accumulator"
|
repository = "https://git.txmn.tk/tuxmain/median-accumulator"
|
||||||
|
|
@ -11,7 +11,7 @@ categories = ["algorithms", "data-structures", "no-std"]
|
||||||
keywords = ["median"]
|
keywords = ["median"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cc-traits = { version = "2.0.0", default_features = false }
|
cc-traits = { version = "2.0.0", default-features = false }
|
||||||
smallvec = { version = "^1.6", optional = true }
|
smallvec = { version = "^1.6", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
@ -21,9 +21,9 @@ smallvec = ["dep:smallvec", "cc-traits/smallvec"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = { version = "0.5.1", features = ["html_reports"] }
|
criterion = { version = "0.8.2", features = ["html_reports"] }
|
||||||
medianheap = "0.4.1"
|
medianheap = "0.4.1"
|
||||||
rand = "0.8.5"
|
rand = "0.10"
|
||||||
smallvec = "^1.6"
|
smallvec = "^1.6"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ For other collections than `Vec` or `SmallVec`, you must implement [cc-traits](h
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
CopyLeft 2022-2024 Pascal Engélibert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/)
|
CopyLeft 2022-2026 Pascal Engélibert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
|
||||||
use rand::Rng;
|
use rand::RngExt;
|
||||||
|
|
||||||
static ITERS: u32 = 10_000;
|
static ITERS: u32 = 10_000;
|
||||||
|
|
||||||
fn compare_crates(c: &mut Criterion) {
|
fn compare_crates(c: &mut Criterion) {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
let mut group = c.benchmark_group("Comparison");
|
let mut group = c.benchmark_group("Comparison");
|
||||||
for redundancy in [1, 5, 10, 20, 40] {
|
for redundancy in [1, 5, 10, 20, 40] {
|
||||||
let samples: Vec<u32> = (0..ITERS)
|
let samples: Vec<u32> = (0..ITERS)
|
||||||
.map(|_| rng.gen_range(0..ITERS / redundancy))
|
.map(|_| rng.random_range(0..ITERS / redundancy))
|
||||||
.collect();
|
.collect();
|
||||||
group.bench_with_input(
|
group.bench_with_input(
|
||||||
BenchmarkId::new("median_accumulator", redundancy),
|
BenchmarkId::new("median_accumulator", redundancy),
|
||||||
|
|
@ -17,7 +17,7 @@ fn compare_crates(c: &mut Criterion) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut median = median_accumulator::vec::MedianAcc::new();
|
let mut median = median_accumulator::vec::MedianAcc::new();
|
||||||
samples.iter().for_each(|s| median.push(*s));
|
samples.iter().for_each(|s| median.push(*s));
|
||||||
black_box(median.get_median());
|
std::hint::black_box(median.get_median());
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -28,7 +28,7 @@ fn compare_crates(c: &mut Criterion) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut median = medianheap::MedianHeap::new();
|
let mut median = medianheap::MedianHeap::new();
|
||||||
samples.iter().for_each(|s| median.push(*s));
|
samples.iter().for_each(|s| median.push(*s));
|
||||||
black_box(median.median());
|
std::hint::black_box(median.median());
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
30
src/lib.rs
30
src/lib.rs
|
|
@ -15,6 +15,13 @@
|
||||||
//! In doc comments, _N_ represents the number of samples, _D_ represents the number of different values taken by the samples.
|
//! In doc comments, _N_ represents the number of samples, _D_ represents the number of different values taken by the samples.
|
||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
#![deny(non_ascii_idents)]
|
||||||
|
#![deny(unnameable_types)]
|
||||||
|
#![deny(unreachable_pub)]
|
||||||
|
#![deny(unstable_features)]
|
||||||
|
#![warn(unused_qualifications)]
|
||||||
|
#![allow(clippy::tabs_in_doc_comments)]
|
||||||
|
|
||||||
mod traits;
|
mod traits;
|
||||||
|
|
||||||
|
|
@ -34,25 +41,26 @@ pub struct MedianAcc<
|
||||||
_t: core::marker::PhantomData<T>,
|
_t: core::marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Aliases for `Vec` backend
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod vec {
|
pub mod vec {
|
||||||
|
/// Median accumulator using a `Vec`
|
||||||
pub type MedianAcc<T> = crate::MedianAcc<T, Vec<(T, u32)>>;
|
pub type MedianAcc<T> = crate::MedianAcc<T, Vec<(T, u32)>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computed median
|
/// Computed median
|
||||||
///
|
|
||||||
/// `Two` is when the median is the mean of the two values.
|
|
||||||
/// In this case, `result.0 < result.1`.
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum MedianResult<T: Clone + Ord> {
|
pub enum MedianResult<T: Clone + Ord> {
|
||||||
|
/// Median is an element from the list
|
||||||
One(T),
|
One(T),
|
||||||
|
/// Median is the mean of these two values from the list
|
||||||
|
///
|
||||||
|
/// It is guaranteed that `result.0 < result.1`.
|
||||||
Two(T, T),
|
Two(T, T),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<T: Clone + Ord, V: DerefMut<Target = [(T, u32)]> + cc_traits::VecMut<(T, u32)> + InsertIndex>
|
||||||
T: Clone + Ord,
|
MedianAcc<T, V>
|
||||||
V: DerefMut<Target = [(T, u32)]> + cc_traits::VecMut<(T, u32)> + InsertIndex,
|
|
||||||
> MedianAcc<T, V>
|
|
||||||
{
|
{
|
||||||
/// Create an empty accumulator
|
/// Create an empty accumulator
|
||||||
///
|
///
|
||||||
|
|
@ -211,7 +219,7 @@ impl<
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::RngExt;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
fn naive_median<T: Clone + Ord>(samples: &mut [T]) -> Option<MedianResult<T>> {
|
fn naive_median<T: Clone + Ord>(samples: &mut [T]) -> Option<MedianResult<T>> {
|
||||||
|
|
@ -236,11 +244,11 @@ mod tests {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn correctness() {
|
fn correctness() {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
for _ in 0..100_000 {
|
for _ in 0..100_000 {
|
||||||
let len: usize = rng.gen_range(0..100);
|
let len: usize = rng.random_range(0..100);
|
||||||
let mut samples: Vec<i32> = (0..len).map(|_| rng.gen_range(-100..100)).collect();
|
let mut samples: Vec<i32> = (0..len).map(|_| rng.random_range(-100..100)).collect();
|
||||||
|
|
||||||
let mut median = vec::MedianAcc::new();
|
let mut median = vec::MedianAcc::new();
|
||||||
for sample in samples.iter() {
|
for sample in samples.iter() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
/// Collection where an item can be inserted at a given index.
|
/// Collection where an item can be inserted at a given index.
|
||||||
pub trait InsertIndex: cc_traits::Collection {
|
pub trait InsertIndex: cc_traits::Collection {
|
||||||
|
/// Output type of inserting at an index (may be `()`)
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
/// Insert `element` to the collection at `index`
|
||||||
fn insert_index(
|
fn insert_index(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue