fn integer_reference(value: i64) -> Result { let failure = &FaultInfo { source: "reference", line: 1, column: 1, message: "integer arithmetic fault", }; value .checked_mul(3) .ok_or(failure)? .checked_add(7) .ok_or(failure)? .checked_div(2) .ok_or(failure) } fn list_reference(values: &[i64]) -> Result { let failure = &FaultInfo { source: "reference", line: 1, column: 1, message: "integer overflow", }; values .iter() .try_fold(0i64, |sum, value| sum.checked_add(*value)) .ok_or(failure) } fn text_reference(first: &str, second: &str) -> Result { let mut result = String::with_capacity(first.len() + second.len()); result.push_str(first); result.push_str(second); Ok(result) } fn sample( name: &str, sample: usize, implementation: &str, count: usize, mut operation: impl FnMut(usize) -> usize, ) { let start = Instant::now(); let mut checksum = 0usize; for position in 0..count { checksum = checksum.wrapping_add(black_box(operation(black_box(position)))); } println!( "{name},{sample},{implementation},{},{checksum}", start.elapsed().as_nanos() ); } fn main() { let values: Vec = (0..1024) .map(|position| (position * 37 % 100) as i64) .collect(); let text = "雪山远处有树林,近处有人撑伞。".repeat(4); for value in [i64::MIN, -123, -1, 0, 100, i64::MAX] { assert_eq!( GENERATED_INTEGER(value).map_err(|_| ()), integer_reference(value).map_err(|_| ()) ); } assert_eq!( GENERATED_LIST(&values).unwrap(), list_reference(&values).unwrap() ); assert!(GENERATED_LIST(&[i64::MAX, 1]).is_err()); assert!(list_reference(&[i64::MAX, 1]).is_err()); assert_eq!( GENERATED_TEXT(&text, &text).unwrap(), text_reference(&text, &text).unwrap() ); println!("case,sample,implementation,elapsed_ns,checksum"); // 求和两侧共用计时函数,保留同函数 control,避免把调用端布局计入生成器差距。 compare( "list_sum_1024", &values, 40_000, GENERATED_LIST, list_reference, |value| *value as u64, ); for iteration in 0..9 { for generated in if iteration % 2 == 0 { [true, false] } else { [false, true] } { let implementation = if generated { "dever" } else { "rust" }; if generated { sample( "checked_int", iteration, implementation, 2_000_000, |position| GENERATED_INTEGER(position as i64).unwrap() as usize, ); sample("text_join", iteration, implementation, 300_000, |_| { black_box(GENERATED_TEXT(black_box(&text), black_box(&text)).unwrap()).len() }); } else { sample( "checked_int", iteration, implementation, 2_000_000, |position| integer_reference(position as i64).unwrap() as usize, ); sample("text_join", iteration, implementation, 300_000, |_| { black_box(text_reference(black_box(&text), black_box(&text)).unwrap()).len() }); } } } }