Skip to content

Commit

Permalink
Primary caching 1: more VecDeque extensions (#4592)
Browse files Browse the repository at this point in the history
Adding some more `VecDeque` extensions that are used by the upcoming
cache implementation.

Also made sure to _not_ run these benchmarks on CI since they are only
useful when iterating specifically on the implementation of these
extensions and are not worth the CI compute time otherwise.

Some numbers for posterity / git log (5950X, Arch):
```
vec_deque/insert_range/prefilled/back           1.00      5.6±0.07µs 170.8 MElem/sec
vec_deque/insert_range/prefilled/front          1.00      5.5±0.12µs 172.4 MElem/sec
vec_deque/insert_range/prefilled/middle         1.00      7.2±0.28µs 131.7 MElem/sec
vec_deque/remove/prefilled/back                 1.00      2.5±0.04µs 384.2 KElem/sec
vec_deque/remove/prefilled/front                1.00      2.5±0.03µs 390.7 KElem/sec
vec_deque/remove/prefilled/middle               1.00      3.3±0.13µs 292.1 KElem/sec
vec_deque/remove_range/prefilled/back           1.00      2.5±0.12µs 375.8 MElem/sec
vec_deque/remove_range/prefilled/front          1.00      2.5±0.11µs 378.4 MElem/sec
vec_deque/remove_range/prefilled/middle         1.00      5.2±0.25µs 182.7 MElem/sec
vec_deque/swap_remove/prefilled/back            1.00      2.6±0.02µs 381.6 KElem/sec
vec_deque/swap_remove/prefilled/front           1.00      2.6±0.05µs 380.8 KElem/sec
vec_deque/swap_remove/prefilled/middle          1.00      2.5±0.08µs 383.3 KElem/sec
vec_deque/swap_remove_front/prefilled/back      1.00      2.5±0.05µs 392.0 KElem/sec
vec_deque/swap_remove_front/prefilled/front     1.00      2.5±0.10µs 394.2 KElem/sec
vec_deque/swap_remove_front/prefilled/middle    1.00      2.6±0.02µs 378.8 KElem/sec
```

---

Part of the primary caching series of PR (index search, joins,
deserialization):
- #4592
- #4593
  • Loading branch information
teh-cmc authored Dec 22, 2023
1 parent c66ee63 commit 803a1cd
Show file tree
Hide file tree
Showing 3 changed files with 331 additions and 86 deletions.
262 changes: 182 additions & 80 deletions crates/re_log_types/benches/vec_deque_ext.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
//! Simple benchmark suite to keep track of how the different removal methods for [`VecDeque`]
//! behave in practice.
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;

use std::collections::VecDeque;

use criterion::{criterion_group, criterion_main, Criterion};
use itertools::Itertools;

use re_log_types::VecDequeRemovalExt as _;
use re_log_types::{VecDequeInsertionExt as _, VecDequeRemovalExt as _};

// ---

criterion_group!(benches, remove, swap_remove, swap_remove_front);
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;

criterion_group!(
benches,
insert_range,
remove_range,
remove,
swap_remove,
swap_remove_front,
);
criterion_main!(benches);

// ---
Expand All @@ -21,109 +29,203 @@ criterion_main!(benches);
#[cfg(debug_assertions)]
mod constants {
pub const INITIAL_NUM_ENTRIES: usize = 1;
pub const NUM_MODIFIED_ELEMENTS: usize = 1;
}

#[cfg(not(debug_assertions))]
mod constants {
pub const INITIAL_NUM_ENTRIES: usize = 20_000;
pub const NUM_MODIFIED_ELEMENTS: usize = 1_000;
}

#[allow(clippy::wildcard_imports)]
use self::constants::*;

// ---

fn remove(c: &mut Criterion) {
{
let mut group = c.benchmark_group("flat_vec_deque");
group.throughput(criterion::Throughput::Elements(1));
group.bench_function("remove/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove(0);
v
});
fn insert_range(c: &mut Criterion) {
if std::env::var("CI").is_ok() {
return;
}

let inserted = (0..NUM_MODIFIED_ELEMENTS as i64).collect_vec();

let mut group = c.benchmark_group("vec_deque");
group.throughput(criterion::Throughput::Elements(inserted.len() as _));

group.bench_function("insert_range/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.insert_range(0, inserted.clone().into_iter());
v
});
group.bench_function("remove/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove(INITIAL_NUM_ENTRIES / 2);
v
});
});

group.bench_function("insert_range/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.insert_range(INITIAL_NUM_ENTRIES / 2, inserted.clone().into_iter());
v
});
group.bench_function("remove/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove(INITIAL_NUM_ENTRIES - 1);
v
});
});

group.bench_function("insert_range/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.insert_range(INITIAL_NUM_ENTRIES, inserted.clone().into_iter());
v
});
});
}

fn remove_range(c: &mut Criterion) {
if std::env::var("CI").is_ok() {
return;
}

let mut group = c.benchmark_group("vec_deque");
group.throughput(criterion::Throughput::Elements(NUM_MODIFIED_ELEMENTS as _));

group.bench_function("remove_range/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove_range(0..NUM_MODIFIED_ELEMENTS);
v
});
});

group.bench_function("remove_range/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove_range(
INITIAL_NUM_ENTRIES / 2 - NUM_MODIFIED_ELEMENTS / 2
..INITIAL_NUM_ENTRIES / 2 + NUM_MODIFIED_ELEMENTS / 2,
);
v
});
});

group.bench_function("remove_range/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove_range(INITIAL_NUM_ENTRIES - NUM_MODIFIED_ELEMENTS..INITIAL_NUM_ENTRIES);
v
});
});
}

fn swap_remove(c: &mut Criterion) {
{
let mut group = c.benchmark_group("flat_vec_deque");
group.throughput(criterion::Throughput::Elements(1));
group.bench_function("swap_remove/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove(0);
v
});
fn remove(c: &mut Criterion) {
if std::env::var("CI").is_ok() {
return;
}

let mut group = c.benchmark_group("vec_deque");
group.throughput(criterion::Throughput::Elements(1));

group.bench_function("remove/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove(0);
v
});
group.bench_function("swap_remove/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove(INITIAL_NUM_ENTRIES / 2);
v
});
});

group.bench_function("remove/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove(INITIAL_NUM_ENTRIES / 2);
v
});
group.bench_function("swap_remove/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove(INITIAL_NUM_ENTRIES - 1);
v
});
});

group.bench_function("remove/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.remove(INITIAL_NUM_ENTRIES - 1);
v
});
});
}

fn swap_remove(c: &mut Criterion) {
if std::env::var("CI").is_ok() {
return;
}

let mut group = c.benchmark_group("vec_deque");
group.throughput(criterion::Throughput::Elements(1));

group.bench_function("swap_remove/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove(0);
v
});
});

group.bench_function("swap_remove/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove(INITIAL_NUM_ENTRIES / 2);
v
});
});

group.bench_function("swap_remove/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove(INITIAL_NUM_ENTRIES - 1);
v
});
});
}

fn swap_remove_front(c: &mut Criterion) {
{
let mut group = c.benchmark_group("flat_vec_deque");
group.throughput(criterion::Throughput::Elements(1));
group.bench_function("swap_remove_front/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove_front(0);
v
});
if std::env::var("CI").is_ok() {
return;
}

let mut group = c.benchmark_group("vec_deque");
group.throughput(criterion::Throughput::Elements(1));

group.bench_function("swap_remove_front/prefilled/front", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove_front(0);
v
});
group.bench_function("swap_remove_front/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove_front(INITIAL_NUM_ENTRIES / 2);
v
});
});

group.bench_function("swap_remove_front/prefilled/middle", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove_front(INITIAL_NUM_ENTRIES / 2);
v
});
group.bench_function("swap_remove_front/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove_front(INITIAL_NUM_ENTRIES - 1);
v
});
});

group.bench_function("swap_remove_front/prefilled/back", |b| {
let base = create_prefilled();
b.iter(|| {
let mut v: VecDeque<i64> = base.clone();
v.swap_remove_front(INITIAL_NUM_ENTRIES - 1);
v
});
}
});
}

// ---
Expand Down
2 changes: 1 addition & 1 deletion crates/re_log_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub use self::time::{Duration, Time, TimeZone};
pub use self::time_point::{TimeInt, TimePoint, TimeType, Timeline, TimelineName};
pub use self::time_range::{TimeRange, TimeRangeF};
pub use self::time_real::TimeReal;
pub use self::vec_deque_ext::{VecDequeRemovalExt, VecDequeSortingExt};
pub use self::vec_deque_ext::{VecDequeInsertionExt, VecDequeRemovalExt, VecDequeSortingExt};

#[cfg(not(target_arch = "wasm32"))]
pub use self::data_table_batcher::{
Expand Down
Loading

0 comments on commit 803a1cd

Please sign in to comment.