keepsimple1 / mdns-sd

Rust library for mDNS based Service Discovery
Apache License 2.0
102 stars 39 forks source link

perf: optimize u8_slice_to_hex by replacing Vec with String #270

Closed CosminPerRam closed 1 week ago

CosminPerRam commented 1 week ago

It builds a String, which is a Vec at its core, so we can replace it (also avoid to build it afterwards).

A quick benchmark on a 25-length array (about the same difference with the doc/test example one):

test tests::original         ... bench:         107.91 ns/iter (+/- 5.20)
test tests::string_container ... bench:          85.96 ns/iter (+/- 7.89)

(Ryzen 5 3600, Windows 11)

Benchmark code Run via `cargo +nightly bench`. ```rust #![feature(test)] extern crate test; const HEX_TABLE: [u8; 16] = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f', ]; fn u8_slice_to_hex(slice: &[u8]) -> String { let mut hex = Vec::with_capacity(slice.len() * 2 + 2); hex.push(b'0'); hex.push(b'x'); for b in slice.iter() { hex.push(HEX_TABLE[(b >> 4) as usize]); hex.push(HEX_TABLE[(b & 0x0F) as usize]); } String::from_utf8(hex).unwrap() } const HEX_TABLE2: [char; 16] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', ]; fn u8_slice_to_hex2(slice: &[u8]) -> String { let mut hex = String::with_capacity(slice.len() * 2 + 2); hex.push_str("0x"); for b in slice { hex.push(HEX_TABLE2[(b >> 4) as usize]); hex.push(HEX_TABLE2[(b & 0x0F) as usize]); } hex } const SOME_NUMS: [u8; 25] = [ 12, 98, 54, 213, 47, 162, 89, 73, 250, 34, 150, 19, 245, 8, 60, 111, 203, 77, 135, 42, 176, 29, 91, 68, 231, ]; #[cfg(test)] mod tests { use super::*; use test::Bencher; #[bench] fn original(b: &mut Bencher) { b.iter(|| u8_slice_to_hex(&SOME_NUMS)); } #[bench] fn string_container(b: &mut Bencher) { b.iter(|| u8_slice_to_hex2(&SOME_NUMS)); } } ```