Advertisement
Guest User

Benchmark #90247

a guest
Oct 25th, 2021
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.96 KB | None | 0 0
  1. #![feature(bench_black_box)]
  2. #![feature(test)]
  3.  
  4. extern crate test;
  5. use test::Bencher;
  6.  
  7. pub struct Duration {
  8.     secs: u64,
  9.     nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
  10. }
  11.  
  12. pub struct FromSecsError {
  13.     kind: FromSecsErrorKind,
  14. }
  15.  
  16. enum FromSecsErrorKind {
  17.     // Value is not a finite value (either infinity or NaN).
  18.     NonFinite,
  19.     // Value is too large to store in a `Duration`.
  20.     Overflow,
  21.     // Value is less than `0.0`.
  22.     Negative,
  23. }
  24.  
  25. pub fn try_from_secs_f64_libm(secs: f64) -> Result<Duration, FromSecsError> {
  26.     const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
  27.     const NANOS_PER_SEC: u32 = 1_000_000_000;
  28.    
  29.     let nanos = secs * (NANOS_PER_SEC as f64);
  30.     if !nanos.is_finite() {
  31.         Err(FromSecsError { kind: FromSecsErrorKind::NonFinite })
  32.     } else if nanos >= MAX_NANOS_F64 {
  33.         Err(FromSecsError { kind: FromSecsErrorKind::Overflow })
  34.     } else if nanos < 0.0 {
  35.         Err(FromSecsError { kind: FromSecsErrorKind::Negative })
  36.     } else {
  37.         let nanos = nanos as u128;
  38.         Ok(Duration {
  39.             secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
  40.             nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
  41.         })
  42.     }
  43. }
  44.  
  45. pub fn try_from_secs_f64_frac(secs: f64) -> Result<Duration, FromSecsError> {
  46.     const NANOS_PER_SEC: u32 = 1_000_000_000;
  47.     const FRACT_BITS: u64 = 52;
  48.     const FRACT_MASK: u64 = (1 << FRACT_BITS) - 1;
  49.     const EXP_BITS: u64 = 11;
  50.     const EXP_MASK: u64 = (1 << EXP_BITS) - 1;
  51.     const DIV: u128 = 1u128 << FRACT_BITS;
  52.  
  53.     if secs.is_sign_negative() {
  54.         return Err(FromSecsError { kind: FromSecsErrorKind::Negative });
  55.     } else if !secs.is_finite() {
  56.         return Err(FromSecsError { kind: FromSecsErrorKind::NonFinite });
  57.     }
  58.  
  59.     let bits = secs.to_bits();
  60.     let fract = (bits & FRACT_MASK) | (FRACT_MASK + 1);
  61.     let exp = ((bits >> FRACT_BITS) & EXP_MASK) as i32 - 1023;
  62.  
  63.     let (secs, nanos) = match exp {
  64.         -1023..=-33 => (0, 0),
  65.         -32..=-1 => {
  66.             let t = fract >> exp.abs();
  67.             let nanos = (NANOS_PER_SEC as u128 * (t as u128)) / DIV;
  68.             (0, nanos as u32)
  69.         }
  70.         0..=51 => {
  71.             let secs = fract >> (FRACT_BITS - exp as u64);
  72.             let t = (fract << exp) & FRACT_MASK;
  73.             let nanos = (NANOS_PER_SEC as u128 * (t as u128)) / DIV;
  74.             (secs, nanos as u32)
  75.         }
  76.         52..=63 => {
  77.             let secs = fract << (exp as u64 - FRACT_BITS);
  78.             (secs, 0)
  79.         }
  80.         _ => return Err(FromSecsError { kind: FromSecsErrorKind::Overflow }),
  81.     };
  82.  
  83.     Ok(Duration { secs, nanos })
  84. }
  85.  
  86. pub fn try_from_secs_f64_frac_reordered(secs: f64) -> Result<Duration, FromSecsError> {
  87.     const NANOS_PER_SEC: u32 = 1_000_000_000;
  88.     const FRACT_BITS: u64 = 52;
  89.     const FRACT_MASK: u64 = (1 << FRACT_BITS) - 1;
  90.     const EXP_BITS: u64 = 11;
  91.     const EXP_MASK: u64 = (1 << EXP_BITS) - 1;
  92.     const DIV: u128 = 1u128 << FRACT_BITS;
  93.  
  94.     if secs.is_sign_negative() {
  95.         return Err(FromSecsError { kind: FromSecsErrorKind::Negative });
  96.     } else if !secs.is_finite() {
  97.         return Err(FromSecsError { kind: FromSecsErrorKind::NonFinite });
  98.     }
  99.  
  100.     let bits = secs.to_bits();
  101.     let fract = (bits & FRACT_MASK) | (FRACT_MASK + 1);
  102.     let exp = ((bits >> FRACT_BITS) & EXP_MASK) as i32 - 1023;
  103.  
  104.     let (secs, nanos) = match exp {
  105.         0..=51 => {
  106.             let secs = fract >> (FRACT_BITS - exp as u64);
  107.             let t = (fract << exp) & FRACT_MASK;
  108.             let nanos = (NANOS_PER_SEC as u128 * (t as u128)) / DIV;
  109.             (secs, nanos as u32)
  110.         }
  111.         -32..=-1 => {
  112.             let t = fract >> exp.abs();
  113.             let nanos = (NANOS_PER_SEC as u128 * (t as u128)) / DIV;
  114.             (0, nanos as u32)
  115.         }
  116.         -1023..=-33 => (0, 0),
  117.         52..=63 => {
  118.             let secs = fract << (exp as u64 - FRACT_BITS);
  119.             (secs, 0)
  120.         }
  121.         _ => return Err(FromSecsError { kind: FromSecsErrorKind::Overflow }),
  122.     };
  123.  
  124.     Ok(Duration { secs, nanos })
  125. }
  126.  
  127. macro_rules! bench {
  128.     ($name:ident, $num:expr) => {
  129.         mod $name {
  130.             bench!($num);
  131.         }
  132.     };
  133.     ($num:expr) => {
  134.         #[bench]
  135.         fn try_from_secs_f64_libm(b: &mut test::Bencher) {
  136.             b.iter(|| crate::try_from_secs_f64_libm(std::hint::black_box($num)));
  137.         }
  138.         #[bench]
  139.         fn try_from_secs_f64_frac(b: &mut test::Bencher) {
  140.             b.iter(|| crate::try_from_secs_f64_frac(std::hint::black_box($num)));
  141.         }
  142.         #[bench]
  143.         fn try_from_secs_f64_frac_reordered(b: &mut test::Bencher) {
  144.             b.iter(|| crate::try_from_secs_f64_frac_reordered(std::hint::black_box($num)));
  145.         }
  146.     };
  147. }
  148.  
  149. bench!(negative, -500.0);
  150. bench!(zero, 0.0);
  151. bench!(one, 1.0);
  152. bench!(megapi, 3.14e5);
  153. bench!(thirteen, 30.0);
  154. bench!(small, 8000.0);
  155. bench!(medium, 85623.8745);
  156. bench!(big, 99995412.2554122554);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement