iter_cartesian 0.1.0

A Cartesian product iterator with double-ended iteration and O(1) length queries.
Documentation
use criterion::{BatchSize, BenchmarkId, Criterion, criterion_group, criterion_main};
use iter_cartesian::CartesianExt;
use std::hint::black_box;

fn bench_len(c: &mut Criterion) {
    let mut group = c.benchmark_group("Cartesian_Len_O1");
    group.sample_size(200);

    for size in [10, 1000, 100000] {
        let total_elements = size as u64 * size as u64;
        group.bench_with_input(
            BenchmarkId::from_parameter(total_elements),
            &size,
            |b, &s| {
                let iter = (0..s).cartesian(0..s);
                b.iter(|| black_box(iter.len()))
            },
        );
    }
    group.finish();
}

fn bench_overrides(c: &mut Criterion) {
    let mut group = c.benchmark_group("Override_Efficiency");

    // nth() should be O(1) — timing must be flat regardless of jump distance.
    for jump in [10, 100_000, 1_000_000] {
        group.bench_with_input(BenchmarkId::new("nth_jump", jump), &jump, |b, &j| {
            b.iter_batched(
                || (0..2_000_000).cartesian(0..2_000_000),
                |mut iter| black_box(iter.nth(j)),
                BatchSize::SmallInput,
            )
        });
    }

    // count() delegates to len() and must be O(1).
    group.bench_function("count_is_len", |b| {
        let iter = (0..1000).cartesian(0..1000);
        b.iter(|| black_box(iter.clone().count()))
    });

    group.finish();
}

fn bench_comparison(c: &mut Criterion) {
    let mut group = c.benchmark_group("Collect_Comparison");
    let size = 1000;

    group.bench_function("cartesian_ext_collect", |b| {
        b.iter(|| {
            let v: Vec<(i32, i32)> = (0..size).cartesian(0..size).collect();
            black_box(v)
        })
    });

    group.bench_function("flat_map_collect", |b| {
        b.iter(|| {
            let v: Vec<(i32, i32)> = (0..size)
                .flat_map(|i| (0..size).map(move |j| (i, j)))
                .collect();
            black_box(v)
        })
    });

    group.finish();
}

criterion_group!(benches, bench_len, bench_overrides, bench_comparison);
criterion_main!(benches);