use criterion::{Criterion, criterion_group, criterion_main}; use std::hint::black_box; use std::process; use tokio::runtime::Runtime; use clash_verge_draft::Draft; #[derive(Default, Clone, Debug)] struct IVerge { enable_auto_launch: Option, enable_tun_mode: Option, } fn make_draft() -> Draft { let verge = IVerge { enable_auto_launch: Some(true), enable_tun_mode: Some(false), }; Draft::new(verge) } pub fn bench_draft(c: &mut Criterion) { let rt = Runtime::new().unwrap_or_else(|e| { eprintln!("Tokio runtime init failed: {e}"); process::exit(1); }); let mut group = c.benchmark_group("draft"); group.sample_size(100); group.warm_up_time(std::time::Duration::from_millis(300)); group.measurement_time(std::time::Duration::from_secs(1)); group.bench_function("data_mut", |b| { b.iter(|| { let draft = black_box(make_draft()); draft.edit_draft(|d| d.enable_tun_mode = Some(true)); black_box(&draft.latest_arc().enable_tun_mode); }); }); group.bench_function("draft_mut_first", |b| { b.iter(|| { let draft = black_box(make_draft()); draft.edit_draft(|d| d.enable_auto_launch = Some(false)); let latest = draft.latest_arc(); black_box(&latest.enable_auto_launch); }); }); group.bench_function("draft_mut_existing", |b| { b.iter(|| { let draft = black_box(make_draft()); { draft.edit_draft(|d| { d.enable_tun_mode = Some(true); }); let latest1 = draft.latest_arc(); black_box(&latest1.enable_tun_mode); } draft.edit_draft(|d| { d.enable_tun_mode = Some(false); }); let latest2 = draft.latest_arc(); black_box(&latest2.enable_tun_mode); }); }); group.bench_function("latest_arc", |b| { b.iter(|| { let draft = black_box(make_draft()); let latest = draft.latest_arc(); black_box(&latest.enable_auto_launch); }); }); group.bench_function("apply", |b| { b.iter(|| { let draft = black_box(make_draft()); { draft.edit_draft(|d| { d.enable_auto_launch = Some(false); }); } draft.apply(); black_box(&draft); }); }); group.bench_function("discard", |b| { b.iter(|| { let draft = black_box(make_draft()); { draft.edit_draft(|d| { d.enable_auto_launch = Some(false); }); } draft.discard(); black_box(&draft); }); }); group.bench_function("with_data_modify_async", |b| { b.to_async(&rt).iter(|| async { let draft = black_box(make_draft()); let _: Result<(), anyhow::Error> = draft .with_data_modify::<_, _, _>(|mut box_data| async move { box_data.enable_auto_launch = Some(!box_data.enable_auto_launch.unwrap_or(false)); Ok((box_data, ())) }) .await; }); }); group.finish(); } criterion_group!(benches, bench_draft); criterion_main!(benches);