use criterion::{criterion_group, criterion_main, BatchSize, Criterion, Throughput};
use smpp34::{decode_tlvs, deliver_sm, encode_tlvs, submit_sm, CommandHeader, Tlv, TlvTag};
fn message_pdu(command_id: u32, short_message: &[u8]) -> Vec<u8> {
let mut body = Vec::new();
body.push(0); body.push(1); body.push(1); body.extend_from_slice(b"12345\0"); body.push(1); body.push(1); body.extend_from_slice(b"31600000000\0"); body.push(0); body.push(0); body.push(0); body.push(0); body.push(0); body.push(0); body.push(0); body.push(0); body.push(0); body.push(short_message.len() as u8); body.extend_from_slice(short_message);
let cmd_len = (16 + body.len()) as u32;
let mut pdu = Vec::with_capacity(cmd_len as usize);
pdu.extend_from_slice(&cmd_len.to_be_bytes());
pdu.extend_from_slice(&command_id.to_be_bytes());
pdu.extend_from_slice(&0u32.to_be_bytes()); pdu.extend_from_slice(&1u32.to_be_bytes()); pdu.extend_from_slice(&body);
pdu
}
fn sample_tlvs() -> Vec<Tlv> {
vec![
Tlv::from_tag(TlvTag::SarMsgRefNum, 0x1234u16.to_be_bytes().to_vec()),
Tlv::from_tag(TlvTag::SarTotalSegments, vec![3]),
Tlv::from_tag(TlvTag::SarSegmentSeqnum, vec![1]),
Tlv::from_tag(
TlvTag::MessagePayload,
b"a longer concatenated segment".to_vec(),
),
]
}
fn bench_codec(c: &mut Criterion) {
let sm = b"Hello, this is a test SMS of fairly typical length.";
let submit_bytes = message_pdu(0x0000_0004, sm);
let deliver_bytes = message_pdu(0x0000_0005, sm);
let submit_val = {
let h = CommandHeader::decode(&submit_bytes).expect("valid header");
submit_sm::decode(h, &submit_bytes).expect("valid submit_sm fixture")
};
let deliver_val = {
let h = CommandHeader::decode(&deliver_bytes).expect("valid header");
deliver_sm::decode(h, &deliver_bytes).expect("valid deliver_sm fixture")
};
let mut g = c.benchmark_group("codec");
g.throughput(Throughput::Elements(1));
g.bench_function("submit_sm/decode", |b| {
b.iter(|| {
let h = CommandHeader::decode(&submit_bytes).unwrap();
submit_sm::decode(h, &submit_bytes).unwrap()
})
});
g.bench_function("submit_sm/encode", |b| {
b.iter_batched(|| submit_val.clone(), |p| p.encode(), BatchSize::SmallInput)
});
g.bench_function("deliver_sm/decode", |b| {
b.iter(|| {
let h = CommandHeader::decode(&deliver_bytes).unwrap();
deliver_sm::decode(h, &deliver_bytes).unwrap()
})
});
g.bench_function("deliver_sm/encode", |b| {
b.iter_batched(
|| deliver_val.clone(),
|p| p.encode(),
BatchSize::SmallInput,
)
});
let tlvs = sample_tlvs();
let tlv_bytes = encode_tlvs(&tlvs);
g.bench_function("tlv/encode", |b| b.iter(|| encode_tlvs(&tlvs)));
g.bench_function("tlv/decode", |b| b.iter(|| decode_tlvs(&tlv_bytes)));
g.finish();
}
criterion_group!(benches, bench_codec);
criterion_main!(benches);