#![allow(clippy::unwrap_used, missing_docs)]
use bytes::{Bytes, BytesMut};
use criterion::{Criterion, Throughput, criterion_group, criterion_main};
use std::hint::black_box;
use tds_protocol::{
encode_sql_batch,
packet::{PACKET_HEADER_SIZE, PacketHeader, PacketStatus, PacketType},
prelogin::{EncryptionLevel, PreLogin},
};
fn bench_packet_header_encode(c: &mut Criterion) {
let header = PacketHeader::new(PacketType::SqlBatch, PacketStatus::END_OF_MESSAGE, 1000);
c.bench_function("packet_header_encode", |b| {
b.iter(|| {
let mut buf = BytesMut::with_capacity(PACKET_HEADER_SIZE);
header.encode(&mut buf);
black_box(buf)
})
});
}
fn bench_packet_header_decode(c: &mut Criterion) {
let header = PacketHeader::new(PacketType::SqlBatch, PacketStatus::END_OF_MESSAGE, 1000);
let mut buf = BytesMut::with_capacity(PACKET_HEADER_SIZE);
header.encode(&mut buf);
let encoded = buf.freeze();
c.bench_function("packet_header_decode", |b| {
b.iter(|| {
let mut cursor = encoded.clone();
let decoded = PacketHeader::decode(&mut cursor).unwrap();
black_box(decoded)
})
});
}
fn bench_prelogin_encode(c: &mut Criterion) {
let prelogin = PreLogin::new()
.with_encryption(EncryptionLevel::On)
.with_mars(true);
c.bench_function("prelogin_encode", |b| {
b.iter(|| {
let encoded = prelogin.encode();
black_box(encoded)
})
});
}
fn bench_prelogin_decode(c: &mut Criterion) {
let prelogin = PreLogin::new()
.with_encryption(EncryptionLevel::On)
.with_mars(true);
let encoded = prelogin.encode();
c.bench_function("prelogin_decode", |b| {
b.iter(|| {
let mut cursor = Bytes::copy_from_slice(&encoded);
let decoded = PreLogin::decode(&mut cursor).unwrap();
black_box(decoded)
})
});
}
fn bench_sql_batch_encode(c: &mut Criterion) {
let mut group = c.benchmark_group("sql_batch_encode");
let simple_query = "SELECT 1";
group.throughput(Throughput::Bytes(simple_query.len() as u64));
group.bench_function("simple", |b| {
b.iter(|| {
let encoded = encode_sql_batch(black_box(simple_query));
black_box(encoded)
})
});
let medium_query = "SELECT id, name, email, created_at, updated_at FROM users WHERE status = 'active' AND organization_id = 12345 ORDER BY created_at DESC LIMIT 100";
group.throughput(Throughput::Bytes(medium_query.len() as u64));
group.bench_function("medium", |b| {
b.iter(|| {
let encoded = encode_sql_batch(black_box(medium_query));
black_box(encoded)
})
});
let large_query = "SELECT u.id, u.name, u.email, o.id as order_id, o.total, o.status, \
p.name as product_name, p.price, oi.quantity \
FROM users u \
INNER JOIN orders o ON u.id = o.user_id \
INNER JOIN order_items oi ON o.id = oi.order_id \
INNER JOIN products p ON oi.product_id = p.id \
WHERE u.organization_id = @p1 AND o.created_at >= @p2 AND o.status IN ('pending', 'processing', 'shipped') \
ORDER BY o.created_at DESC, u.name ASC";
group.throughput(Throughput::Bytes(large_query.len() as u64));
group.bench_function("large", |b| {
b.iter(|| {
let encoded = encode_sql_batch(black_box(large_query));
black_box(encoded)
})
});
group.finish();
}
criterion_group!(
benches,
bench_packet_header_encode,
bench_packet_header_decode,
bench_prelogin_encode,
bench_prelogin_decode,
bench_sql_batch_encode,
);
criterion_main!(benches);