196 lines · 6.1 KB · Rust
RawDownload
use std::ops::Range; use criterion::{    black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput,};use rand::prelude::*;use rand::rngs::StdRng;use rope::{Point, Rope};use sum_tree::Bias;use util::RandomCharIter; fn generate_random_text(mut rng: StdRng, text_len: usize) -> String {    RandomCharIter::new(&mut rng).take(text_len).collect()} fn generate_random_rope(rng: StdRng, text_len: usize) -> Rope {    let text = generate_random_text(rng, text_len);    let mut rope = Rope::new();    rope.push(&text);    rope} fn generate_random_rope_ranges(mut rng: StdRng, rope: &Rope) -> Vec<Range<usize>> {    let range_max_len = 50;    let num_ranges = rope.len() / range_max_len;     let mut ranges = Vec::new();    let mut start = 0;    for _ in 0..num_ranges {        let range_start = rope.clip_offset(            rng.gen_range(start..=(start + range_max_len)),            sum_tree::Bias::Left,        );        let range_end = rope.clip_offset(            rng.gen_range(range_start..(range_start + range_max_len)),            sum_tree::Bias::Right,        );         let range = range_start..range_end;        if !range.is_empty() {            ranges.push(range);        }         start = range_end + 1;    }     ranges} fn generate_random_rope_points(mut rng: StdRng, rope: &Rope) -> Vec<Point> {    let num_points = rope.len() / 10;     let mut points = Vec::new();    for _ in 0..num_points {        points.push(rope.offset_to_point(rng.gen_range(0..rope.len())));    }    points} fn rope_benchmarks(c: &mut Criterion) {    static SEED: u64 = 9999;    static KB: usize = 1024;     let rng = StdRng::seed_from_u64(SEED);    let sizes = [4 * KB, 64 * KB];     let mut group = c.benchmark_group("push");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let text = generate_random_text(rng.clone(), *size);             b.iter(|| {                let mut rope = Rope::new();                for _ in 0..10 {                    rope.push(&text);                }            });        });    }    group.finish();     let mut group = c.benchmark_group("append");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let mut random_ropes = Vec::new();            for _ in 0..5 {                random_ropes.push(generate_random_rope(rng.clone(), *size));            }             b.iter(|| {                let mut rope_b = Rope::new();                for rope in &random_ropes {                    rope_b.append(rope.clone())                }            });        });    }    group.finish();     let mut group = c.benchmark_group("slice");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let rope = generate_random_rope(rng.clone(), *size);             b.iter_batched(                || generate_random_rope_ranges(rng.clone(), &rope),                |ranges| {                    for range in ranges.iter() {                        rope.slice(range.clone());                    }                },                BatchSize::SmallInput,            );        });    }    group.finish();     let mut group = c.benchmark_group("bytes_in_range");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let rope = generate_random_rope(rng.clone(), *size);             b.iter_batched(                || generate_random_rope_ranges(rng.clone(), &rope),                |ranges| {                    for range in ranges.iter() {                        let bytes = rope.bytes_in_range(range.clone());                        assert!(bytes.into_iter().count() > 0);                    }                },                BatchSize::SmallInput,            );        });    }    group.finish();     let mut group = c.benchmark_group("chars");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let rope = generate_random_rope(rng.clone(), *size);             b.iter_with_large_drop(|| {                let chars = rope.chars().count();                assert!(chars > 0);            });        });    }    group.finish();     let mut group = c.benchmark_group("clip_point");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let rope = generate_random_rope(rng.clone(), *size);             b.iter_batched(                || generate_random_rope_points(rng.clone(), &rope),                |offsets| {                    for offset in offsets.iter() {                        black_box(rope.clip_point(*offset, Bias::Left));                        black_box(rope.clip_point(*offset, Bias::Right));                    }                },                BatchSize::SmallInput,            );        });    }    group.finish();     let mut group = c.benchmark_group("point_to_offset");    for size in sizes.iter() {        group.throughput(Throughput::Bytes(*size as u64));        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {            let rope = generate_random_rope(rng.clone(), *size);             b.iter_batched(                || generate_random_rope_points(rng.clone(), &rope),                |offsets| {                    for offset in offsets.iter() {                        black_box(rope.point_to_offset(*offset));                    }                },                BatchSize::SmallInput,            );        });    }    group.finish();} criterion_group!(benches, rope_benchmarks);criterion_main!(benches);