#![allow(clippy::identity_op, clippy::needless_range_loop, clippy::erasing_op, clippy::unusual_byte_groupings)]
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use bitkit::{bytes, Bits};
const N: usize = 15;
fn random_distance_matrix(seed: u64) -> [[u32; N]; N] {
let mut d = [[0u32; N]; N];
let mut s = seed;
for i in 0..N {
for j in 0..N {
if i == j { continue; }
s = s.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
d[i][j] = (s >> 33) as u32 % 1000 + 1;
}
}
d
}
fn tsp_bitsrs(dist: &[[u32; N]; N]) -> u32 {
let states = 1usize << N;
let mut dp = vec![u32::MAX; states * N];
dp[(1usize) * N + 0] = 0;
for mask in 1u32..states as u32 {
let mbits = Bits::<u32>::new(mask);
if !mbits.has_bit(0).unwrap() { continue; }
for last in mbits.set_bits() {
if last == 0 && mask != 1 { continue; }
let cur = dp[mask as usize * N + last as usize];
if cur == u32::MAX { continue; }
let unvisited = !mask & ((1u32 << N) - 1);
for next in Bits::<u32>::new(unvisited).set_bits() {
let new_mask = mask | (1u32 << next);
let cand = cur.saturating_add(dist[last as usize][next as usize]);
let slot = &mut dp[new_mask as usize * N + next as usize];
if cand < *slot { *slot = cand; }
}
}
}
let full = (1u32 << N) - 1;
let mut best = u32::MAX;
for last in 1..N {
let val = dp[full as usize * N + last].saturating_add(dist[last][0]);
if val < best { best = val; }
}
best
}
fn tsp_inline(dist: &[[u32; N]; N]) -> u32 {
let states = 1usize << N;
let mut dp = vec![u32::MAX; states * N];
dp[1 * N + 0] = 0;
for mask in 1u32..states as u32 {
if mask & 1 == 0 { continue; }
let mut m = mask;
while m != 0 {
let last = m.trailing_zeros();
m &= m - 1;
if last == 0 && mask != 1 { continue; }
let cur = dp[mask as usize * N + last as usize];
if cur == u32::MAX { continue; }
let mut un = !mask & ((1u32 << N) - 1);
while un != 0 {
let next = un.trailing_zeros();
un &= un - 1;
let new_mask = mask | (1u32 << next);
let cand = cur.saturating_add(dist[last as usize][next as usize]);
let slot = &mut dp[new_mask as usize * N + next as usize];
if cand < *slot { *slot = cand; }
}
}
}
let full = (1u32 << N) - 1;
let mut best = u32::MAX;
for last in 1..N {
let val = dp[full as usize * N + last].saturating_add(dist[last][0]);
if val < best { best = val; }
}
best
}
fn tsp_bitsrs_foreach(dist: &[[u32; N]; N]) -> u32 {
let states = 1usize << N;
let mut dp = vec![u32::MAX; states * N];
dp[(1usize) * N + 0] = 0;
for mask in 1u32..states as u32 {
let mbits = Bits::<u32>::new(mask);
if !mbits.has_bit(0).unwrap() { continue; }
mbits.set_bits().for_each(|last| {
if last == 0 && mask != 1 { return; }
let cur = dp[mask as usize * N + last as usize];
if cur == u32::MAX { return; }
let unvisited = !mask & ((1u32 << N) - 1);
Bits::<u32>::new(unvisited).set_bits().for_each(|next| {
let new_mask = mask | (1u32 << next);
let cand = cur.saturating_add(dist[last as usize][next as usize]);
let slot = &mut dp[new_mask as usize * N + next as usize];
if cand < *slot { *slot = cand; }
});
});
}
let full = (1u32 << N) - 1;
let mut best = u32::MAX;
for last in 1..N {
let val = dp[full as usize * N + last].saturating_add(dist[last][0]);
if val < best { best = val; }
}
best
}
fn bench_tsp(c: &mut Criterion) {
let d = random_distance_matrix(0xDEAD_BEEF_CAFE_BABE);
let mut grp = c.benchmark_group("tsp15");
grp.sample_size(20); grp.bench_function("bits-rs (submasks/set_bits)", |b| {
b.iter(|| black_box(tsp_bitsrs(black_box(&d))))
});
grp.bench_function("inline (raw ops)", |b| {
b.iter(|| black_box(tsp_inline(black_box(&d))))
});
grp.bench_function("bits-rs (for_each fast path)", |b| {
b.iter(|| black_box(tsp_bitsrs_foreach(black_box(&d))))
});
grp.finish();
}
const PACKETS: usize = 10_000;
fn make_packets() -> Vec<[u8; 20]> {
(0..PACKETS).map(|i| {
let i32_ = i as u32;
[
0x45, 0x00, (i32_ >> 8) as u8, i32_ as u8,
(i32_ >> 0) as u8, (i32_ >> 8) as u8, 0x40, 0x00,
64, 6, 0xAB, 0xCD,
192, 168, (i >> 8) as u8, i as u8,
8, 8, 8, 8,
]
}).collect()
}
#[derive(Default)]
struct ParsedSummary {
version_sum: u64,
ihl_sum: u64,
total_length_sum: u64,
ttl_sum: u64,
src_xor: u32,
}
fn parse_bitsrs(pkts: &[[u8; 20]]) -> ParsedSummary {
let mut s = ParsedSummary::default();
for hdr in pkts {
let b0 = Bits::<u8>::new(hdr[0]);
s.version_sum += b0.extract(4..8).unwrap().get() as u64;
s.ihl_sum += b0.extract(0..4).unwrap().get() as u64;
s.total_length_sum += bytes::read_u16_be(&hdr[2..]).unwrap() as u64;
s.ttl_sum += hdr[8] as u64;
s.src_xor ^= bytes::read_u32_be(&hdr[12..]).unwrap();
}
s
}
fn parse_inline(pkts: &[[u8; 20]]) -> ParsedSummary {
let mut s = ParsedSummary::default();
for hdr in pkts {
s.version_sum += (hdr[0] >> 4) as u64;
s.ihl_sum += (hdr[0] & 0xF) as u64;
s.total_length_sum += u16::from_be_bytes([hdr[2], hdr[3]]) as u64;
s.ttl_sum += hdr[8] as u64;
s.src_xor ^= u32::from_be_bytes([hdr[12], hdr[13], hdr[14], hdr[15]]);
}
s
}
fn bench_ipv4(c: &mut Criterion) {
let pkts = make_packets();
let mut grp = c.benchmark_group("ipv4_parse_10k");
grp.bench_function("bits-rs (bytes::read + Bits::extract)", |b| {
b.iter(|| black_box(parse_bitsrs(black_box(&pkts))));
});
grp.bench_function("inline (shift/and/from_be_bytes)", |b| {
b.iter(|| black_box(parse_inline(black_box(&pkts))));
});
grp.finish();
}
fn extract_flags_bitsrs(xs: &[u32]) -> u32 {
let mask = Bits::<u32>::new(0x8080_8080);
let mut acc = 0u32;
for &x in xs {
acc ^= Bits::<u32>::new(x).gather(mask).get();
}
acc
}
fn extract_flags_inline(xs: &[u32]) -> u32 {
let mut acc = 0u32;
for &x in xs {
let a = (x >> 31) & 1;
let b = (x >> 23) & 1;
let c = (x >> 15) & 1;
let d = (x >> 7) & 1;
acc ^= a | (b << 1) | (c << 2) | (d << 3);
}
acc
}
fn bench_sparse_extract(c: &mut Criterion) {
let xs: Vec<u32> = (0..10_000u32).map(|i| i.wrapping_mul(0x9E37_79B1)).collect();
let mut grp = c.benchmark_group("sparse_extract_10k");
grp.bench_function("bits-rs (single gather/PEXT)", |b| {
b.iter(|| black_box(extract_flags_bitsrs(black_box(&xs))))
});
grp.bench_function("inline (shift+and×4)", |b| {
b.iter(|| black_box(extract_flags_inline(black_box(&xs))))
});
grp.finish();
}
fn popcount_sum_bitsrs(xs: &[u64]) -> u64 {
let mut s: u64 = 0;
for &x in xs { s = s.wrapping_add(Bits::<u64>::new(x).count_ones() as u64); }
s
}
fn popcount_sum_inline(xs: &[u64]) -> u64 {
let mut s: u64 = 0;
for &x in xs { s = s.wrapping_add(x.count_ones() as u64); }
s
}
fn bench_popcount_sum(c: &mut Criterion) {
let xs: Vec<u64> = (0..1_000_000u64)
.map(|i| i.wrapping_mul(0x9E37_79B97F4A_7C15))
.collect();
let mut grp = c.benchmark_group("popcount_sum_1M_u64");
grp.bench_function("bits-rs", |b| b.iter(|| black_box(popcount_sum_bitsrs(black_box(&xs)))));
grp.bench_function("primitive", |b| b.iter(|| black_box(popcount_sum_inline(black_box(&xs)))));
grp.finish();
}
criterion_group!(workloads, bench_tsp, bench_ipv4, bench_sparse_extract, bench_popcount_sum);
criterion_main!(workloads);