From 146a2246c223932c3eeff5afc5b60d9496c6ca3d Mon Sep 17 00:00:00 2001 From: copyleftdev Date: Sun, 26 Oct 2025 22:55:10 -0700 Subject: [PATCH] feat(benches): add comprehensive benchmark suite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add arrow_lookup benchmark for IP lookup performance - Add dns_resolution benchmark for resolver operations - Add client_performance benchmark for API client - Configure criterion in all benchmark crates Benchmarks: - Arrow: single lookup, scalar vs SIMD, batch (10/100/1k) - DNS: resolver creation, cache operations - Client: creation, with_config Performance Baselines: - Arrow lookup: targeting <1µs (scalar), <0.2µs (SIMD) - DNS cache stats: <100ns - Client creation: minimal overhead All benchmarks use criterion 0.5 with: - Black box to prevent optimization - Throughput metrics for batch tests - Grouped comparisons (scalar vs SIMD) Fixes #7 --- crates/rasn-arrow/Cargo.toml | 4 + crates/rasn-arrow/benches/arrow_lookup.rs | 80 +++++++++++++++++++ crates/rasn-client/Cargo.toml | 5 ++ .../rasn-client/benches/client_performance.rs | 23 ++++++ crates/rasn-resolver/Cargo.toml | 5 ++ .../rasn-resolver/benches/dns_resolution.rs | 20 +++++ 6 files changed, 137 insertions(+) create mode 100644 crates/rasn-arrow/benches/arrow_lookup.rs create mode 100644 crates/rasn-client/benches/client_performance.rs create mode 100644 crates/rasn-resolver/benches/dns_resolution.rs diff --git a/crates/rasn-arrow/Cargo.toml b/crates/rasn-arrow/Cargo.toml index a2c7c4e..6bd657a 100644 --- a/crates/rasn-arrow/Cargo.toml +++ b/crates/rasn-arrow/Cargo.toml @@ -21,3 +21,7 @@ criterion = "0.5" [[bench]] name = "lookup_bench" harness = false + +[[bench]] +name = "arrow_lookup" +harness = false diff --git a/crates/rasn-arrow/benches/arrow_lookup.rs b/crates/rasn-arrow/benches/arrow_lookup.rs new file mode 100644 index 0000000..3ad7484 --- /dev/null +++ b/crates/rasn-arrow/benches/arrow_lookup.rs @@ -0,0 +1,80 @@ +use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use rasn_arrow::IpRangeTableV4; +use std::path::Path; + +fn load_table() -> IpRangeTableV4 { + let path = Path::new("data/arrow/ip2asn-v4.parquet"); + IpRangeTableV4::from_parquet(path).expect("Failed to load test data") +} + +fn bench_single_lookup(c: &mut Criterion) { + let table = load_table(); + + c.bench_function("arrow_single_lookup", |b| { + b.iter(|| { + // 8.8.8.8 = 0x08080808 (Google DNS) + table.find_ip(black_box(0x08080808)) + }) + }); +} + +fn bench_scalar_vs_simd(c: &mut Criterion) { + let table = load_table(); + + let mut group = c.benchmark_group("lookup_comparison"); + + group.bench_function("scalar_lookup", |b| { + b.iter(|| table.find_ip_scalar(black_box(0x08080808))) + }); + + #[cfg(target_arch = "x86_64")] + { + if is_x86_feature_detected!("avx2") { + group.bench_function("simd_lookup", |b| { + b.iter(|| table.find_ip(black_box(0x08080808))) + }); + } + } + + group.finish(); +} + +fn bench_batch_lookups(c: &mut Criterion) { + let table = load_table(); + + // Test different batch sizes + let sizes = [10, 100, 1000]; + + let test_ips: Vec = vec![ + 0x08080808, // 8.8.8.8 (Google) + 0x01010101, // 1.1.1.1 (Cloudflare) + 0x08080404, // 8.8.4.4 (Google) + 0x09090909, // 9.9.9.9 (Quad9) + 0xC0000201, // 192.0.2.1 (TEST-NET-1) + ]; + + let mut group = c.benchmark_group("batch_lookups"); + + for size in sizes.iter() { + group.throughput(Throughput::Elements(*size as u64)); + + group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| { + b.iter(|| { + for i in 0..size { + let ip = test_ips[i % test_ips.len()]; + black_box(table.find_ip(ip)); + } + }); + }); + } + + group.finish(); +} + +criterion_group!( + benches, + bench_single_lookup, + bench_scalar_vs_simd, + bench_batch_lookups +); +criterion_main!(benches); diff --git a/crates/rasn-client/Cargo.toml b/crates/rasn-client/Cargo.toml index 45ae355..5a8ccdf 100644 --- a/crates/rasn-client/Cargo.toml +++ b/crates/rasn-client/Cargo.toml @@ -18,3 +18,8 @@ thiserror.workspace = true [dev-dependencies] tokio-test = "0.4" +criterion = "0.5" + +[[bench]] +name = "client_performance" +harness = false diff --git a/crates/rasn-client/benches/client_performance.rs b/crates/rasn-client/benches/client_performance.rs new file mode 100644 index 0000000..eef3bcd --- /dev/null +++ b/crates/rasn-client/benches/client_performance.rs @@ -0,0 +1,23 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use rasn_client::ApiClient; + +fn bench_client_creation(c: &mut Criterion) { + c.bench_function("api_client_creation", |b| { + b.iter(|| black_box(ApiClient::new("test-api-key".to_string()))) + }); +} + +fn bench_client_with_config(c: &mut Criterion) { + c.bench_function("api_client_with_config", |b| { + b.iter(|| { + black_box(ApiClient::with_config( + "key".to_string(), + "https://api.test.com".to_string(), + std::time::Duration::from_secs(5), + )) + }) + }); +} + +criterion_group!(benches, bench_client_creation, bench_client_with_config); +criterion_main!(benches); diff --git a/crates/rasn-resolver/Cargo.toml b/crates/rasn-resolver/Cargo.toml index b08618a..767349e 100644 --- a/crates/rasn-resolver/Cargo.toml +++ b/crates/rasn-resolver/Cargo.toml @@ -17,3 +17,8 @@ lru = "0.12" [dev-dependencies] tokio-test = "0.4" +criterion = "0.5" + +[[bench]] +name = "dns_resolution" +harness = false diff --git a/crates/rasn-resolver/benches/dns_resolution.rs b/crates/rasn-resolver/benches/dns_resolution.rs new file mode 100644 index 0000000..41f46a6 --- /dev/null +++ b/crates/rasn-resolver/benches/dns_resolution.rs @@ -0,0 +1,20 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use rasn_resolver::DnsResolver; + +fn bench_resolver_creation(c: &mut Criterion) { + c.bench_function("dns_resolver_creation", |b| { + b.iter(|| black_box(DnsResolver::new().unwrap())) + }); +} + +fn bench_cache_operations(c: &mut Criterion) { + let rt = tokio::runtime::Runtime::new().unwrap(); + let resolver = DnsResolver::new().unwrap(); + + c.bench_function("dns_cache_stats", |b| { + b.iter(|| rt.block_on(async { black_box(resolver.cache_stats().await) })) + }); +} + +criterion_group!(benches, bench_resolver_creation, bench_cache_operations); +criterion_main!(benches);