1#[cfg(feature = "bench")]
2use crate::benching::SamplingData;
3use crate::error::{Error, Result};
4#[cfg(feature = "timer")]
5use crate::timing::TimingData;
6
7#[cfg(feature = "timer")]
9pub(crate) fn ser_timing_data(run_data: TimingData) -> Vec<u8> {
10 let mut v = Vec::with_capacity(16 * 4);
11 v.extend_from_slice(&run_data.min_nanos.to_le_bytes());
12 v.extend_from_slice(&run_data.max_nanos.to_le_bytes());
13 v.extend_from_slice(&run_data.elapsed.to_le_bytes());
14 v.extend_from_slice(&run_data.iterations.to_le_bytes());
15 v
16}
17
18#[cfg(feature = "timer")]
19pub(crate) fn try_de_timing_data(buf: &[u8]) -> Result<TimingData> {
20 if buf.len() != 64 {
21 return Err(Error::new(format!(
22 "Unexpected buffer len for serialized timing data, expected 64 but got {}",
23 buf.len()
24 )));
25 }
26 let min_nanos = u128::from_le_bytes(buf[0..16].try_into().ok().unwrap());
28 let max_nanos = u128::from_le_bytes(buf[16..32].try_into().ok().unwrap());
29 let elapsed = u128::from_le_bytes(buf[32..48].try_into().ok().unwrap());
30 let iterations = u128::from_le_bytes(buf[48..64].try_into().ok().unwrap());
31 Ok(TimingData {
32 min_nanos,
33 max_nanos,
34 elapsed,
35 iterations,
36 })
37}
38
39#[cfg(feature = "bench")]
40pub(crate) fn ser_sampling_data(sampling_data: &SamplingData) -> Vec<u8> {
41 let mut v = Vec::new();
42 let len = sampling_data.samples.len() as u64;
43 v.extend_from_slice(&len.to_le_bytes());
44 for sample in &sampling_data.samples {
45 v.extend_from_slice(&sample.to_le_bytes());
46 }
47 for time in &sampling_data.times {
48 v.extend_from_slice(&time.to_le_bytes());
49 }
50 v
51}
52
53#[cfg(feature = "bench")]
54pub(crate) fn try_de_sampling_data(buf: &[u8]) -> Result<SamplingData> {
55 let buf_len = buf.len();
56 if buf_len < 8 {
57 return Err(Error::new(format!(
58 "Found malformed serialized data, length too short {buf_len}"
59 )));
60 }
61 let len = u64::from_le_bytes(buf[..8].try_into().unwrap());
63 let mut samples = Vec::with_capacity(len as usize);
64 let mut times = Vec::with_capacity(len as usize);
65 let expected_total_len = 8 + len * 16 + len * 8;
66 if buf_len as u64 != expected_total_len {
67 return Err(Error::new(format!("Found malformed serialized data, unexpected length. Expected {expected_total_len} found {buf_len}")));
68 }
69 for i in 0..len {
70 let sample_value_offset = (8 + i * 8) as usize;
71 samples.push(u64::from_le_bytes(
72 buf[sample_value_offset..sample_value_offset + 8]
73 .try_into()
74 .ok()
75 .unwrap(),
76 ));
77 let times_value_offset = (8 + len * 8 + i * 16) as usize;
78 times.push(u128::from_le_bytes(
79 buf[times_value_offset..times_value_offset + 16]
80 .try_into()
81 .ok()
82 .unwrap(),
83 ));
84 }
85 Ok(SamplingData { samples, times })
86}
87
88#[cfg(test)]
89mod tests {
90
91 #[test]
92 #[cfg(feature = "timer")]
93 fn can_ser_de_timing() {
94 let min_nanos = 0;
95 let max_nanos = u128::MAX;
96 let elapsed = 555_555;
97 let iterations = 99_959_599_959;
98 let rd = super::TimingData {
99 min_nanos,
100 max_nanos,
101 elapsed,
102 iterations,
103 };
104 assert_eq!(
105 rd,
106 super::try_de_timing_data(&super::ser_timing_data(rd)).unwrap()
107 );
108 }
109
110 #[test]
111 #[cfg(feature = "bench")]
112 fn can_ser_de_sampling() {
113 let sampling = super::SamplingData {
114 samples: vec![5, 6, 7, 8, 9, 10],
115 times: vec![15, 16, 17, 18, 19, 20],
116 };
117 assert_eq!(
118 sampling,
119 super::try_de_sampling_data(&super::ser_sampling_data(&sampling)).unwrap()
120 );
121 }
122}