dyn_trait_obj.rs
1 use super::*; 2 3 module_group! { 4 name = "Dynamic-Trait-Object"; 5 benches = core, snafu_fat_vs_anyhow_thin 6 } 7 8 9 #[inline(never)] 10 fn more<T>(x: T) -> T 11 { 12 bb(x) 13 } 14 15 16 /// Fundamental uses of passing (as return value or as argument value) fat `dyn Trait` type 17 /// vs. thin static type, without use of the error-helping libraries. 18 fn core(c: &mut Criterion) 19 { 20 bench_group! { (c) name = "Core"; 21 routines = [ 22 "Thin" = || drop(bb(thin())), 23 "Fat" = || drop(bb(fat())), 24 "Thin-More" = || drop(bb(thin_more())), 25 "Fat-More" = || drop(bb(fat_more())), 26 ]; 27 } 28 29 #[derive(Debug)] 30 struct MyError; 31 impl_StdError! { MyError } 32 33 assert!(size_of::<MyError>() == 0); // So Box::new(MyError) won't allocate. 34 assert!(size_of::<Box<MyError>>() == size_of::<usize>()); // It's still a pointer. 35 assert!(size_of::<Box<dyn StdError>>() == 2 * size_of::<usize>()); // Still fat. 36 37 macro_rules! e { 38 () => { 39 bb(Box::new(bb(MyError))) 40 }; 41 } 42 43 fn thin() -> Result<(), Box<MyError>> 44 { 45 Err(e!()) 46 } 47 48 fn fat() -> Result<(), Box<dyn StdError>> 49 { 50 Err(e!()) 51 } 52 53 fn thin_more() -> Result<(), Box<MyError>> 54 { 55 bb(more(bb(Err(bb(more::<Box<MyError>>(e!())))))) 56 } 57 58 fn fat_more() -> Result<(), Box<dyn StdError>> 59 { 60 bb(more(bb(Err(bb(more::<Box<dyn StdError>>(e!())))))) 61 } 62 } 63 64 65 /// Passing (as return value or as argument value) SNAFU's fat `Box<dyn StdError>` type in its 66 /// fatter `Whatever` type vs. Anyhow's thin-box type. 67 fn snafu_fat_vs_anyhow_thin(c: &mut Criterion) 68 { 69 // These avoid needing creation in the first two bench'ed routines. 70 let mut ae: Option<anyhow::Error> = Some(anyhow!("")); 71 #[allow(clippy::useless_format)] 72 let mut se: Option<MyWhatever> = Some(snafu::FromString::without_source(format!(""))); 73 74 bench_group! { (c) name = "Snafu-Fat-Vs-Anyhow-Thin"; 75 routines = [ 76 "Anyhow" = || ae = bb(anyhow(bb(ae.take().unwrap()))).err(), 77 "Snafu" = || se = bb(snafu(bb(se.take().unwrap()))).err(), 78 "Anyhow-Create" = || drop(bb(anyhow_create())), 79 "Snafu-Create" = || drop(bb(snafu_create())), 80 ]; 81 } 82 83 assert!(size_of::<anyhow::Error>() == size_of::<usize>()); 84 85 // Comparable to `Thin-More`. 86 fn anyhow(e: anyhow::Error) -> Result<(), anyhow::Error> 87 { 88 bb(more(bb(Err(bb(more(bb(e))))))) 89 } 90 91 fn anyhow_create() -> Result<(), anyhow::Error> 92 { 93 let e: anyhow::Error = anyhow!(""); 94 anyhow(e) 95 } 96 97 assert!(size_of::<MyWhatever>() >= 2 * size_of::<usize>()); 98 99 // Comparable to `Fat-More`. 100 fn snafu(e: MyWhatever) -> Result<(), MyWhatever> 101 { 102 bb(more(bb(Err(bb(more(bb(e))))))) 103 } 104 105 fn snafu_create() -> Result<(), MyWhatever> 106 { 107 #[allow(clippy::useless_format)] 108 let e: MyWhatever = snafu::FromString::without_source(format!("")); 109 snafu(e) 110 } 111 }