// 隔离同一受检翻倍在内联表达式、Rust 函数边界和 Dever 生成路径上的差异。 // 共享故障元数据以排除错误对象大小和来源内容,原 packages 参照保持不变。 fn shared_fault() -> Fault { GENERATED_DISPATCH(i64::MAX).unwrap_err() } fn dispatch_generated(values: &[i64]) -> Result { GENERATED_DISPATCH(values.first().copied().unwrap_or(0)) } fn adjust_generated(values: &[i64]) -> Result { GENERATED_ADJUST(values.first().copied().unwrap_or(0)) } fn inline_reference(values: &[i64]) -> Result { values .first() .copied() .unwrap_or(0) .checked_mul(2) .ok_or_else(shared_fault) } fn propagated_reference(values: &[i64]) -> Result { let answer = values .first() .copied() .unwrap_or(0) .checked_mul(2) .ok_or_else(shared_fault)?; Ok(answer) } fn helper(value: i64) -> Result { value.checked_mul(2).ok_or_else(shared_fault) } fn helper_reference(values: &[i64]) -> Result { helper(values.first().copied().unwrap_or(0)) } #[inline(always)] fn early_helper(value: i64) -> Result { value.checked_mul(2).ok_or_else(shared_fault) } fn early_helper_reference(values: &[i64]) -> Result { early_helper(values.first().copied().unwrap_or(0)) } fn independent_helper(value: i64) -> Result { value.checked_mul(2).ok_or(&FaultInfo { message: "integer arithmetic fault", source: "reference.dever", line: 1, column: 1, }) } fn independent_helper_reference(values: &[i64]) -> Result { independent_helper(values.first().copied().unwrap_or(0)) } fn propagated_helper(value: i64) -> Result { let answer = value.checked_mul(2).ok_or_else(shared_fault)?; Ok(answer) } fn propagated_helper_reference(values: &[i64]) -> Result { propagated_helper(values.first().copied().unwrap_or(0)) } fn batch_generated(values: &[i64]) -> Result { let mut total = 0i64; for value in values { total = total .checked_add(GENERATED_DISPATCH(*value)?) .ok_or_else(shared_fault)?; } Ok(total) } fn batch_reference(values: &[i64]) -> Result { let mut total = 0i64; for value in values { let doubled = value.checked_mul(2).ok_or_else(shared_fault)?; total = total.checked_add(doubled).ok_or_else(shared_fault)?; } Ok(total) } fn main() { let operations = [ dispatch_generated as fn(&[i64]) -> Result, adjust_generated, inline_reference, propagated_reference, helper_reference, early_helper_reference, propagated_helper_reference, ]; for value in [ i64::MIN, i64::MIN / 2 - 1, i64::MIN / 2, -1, 0, 1, 21, i64::MAX / 2, i64::MAX / 2 + 1, i64::MAX, ] { for operation in operations { assert_eq!( operation(&[value]).map_err(|fault| fault.to_string()), inline_reference(&[value]).map_err(|fault| fault.to_string()) ); } assert_eq!( independent_helper_reference(&[value]).map_err(|_| ()), inline_reference(&[value]).map_err(|_| ()) ); } for (name, operation) in [ ( "dispatch", dispatch_generated as fn(&[i64]) -> Result, ), ("adjust", adjust_generated), ("propagated", propagated_reference), ("helper", helper_reference), ("early_helper", early_helper_reference), ("independent_helper", independent_helper_reference), ("propagated_helper", propagated_helper_reference), ] { eprintln!( "{name}_equals_dispatch={}", std::ptr::fn_addr_eq( operation, dispatch_generated as fn(&[i64]) -> Result ) ); } let values = (0..256).map(|index| index * 17 - 2000).collect::>(); for input in [ vec![], vec![i64::MAX], vec![i64::MIN], vec![i64::MAX / 2, 1], values.clone(), ] { assert_eq!( batch_generated(&input).map_err(|fault| fault.to_string()), batch_reference(&input).map_err(|fault| fault.to_string()) ); } println!("case,sample,implementation,elapsed_ns,checksum"); compare( "scalar_matched_hot_path", &[21], 3000000, adjust_generated, independent_helper_reference, |value| *value as u64, ); compare( "scalar_inline", &[21], 3000000, dispatch_generated, inline_reference, |value| *value as u64, ); compare_named( "scalar_direct", &[21], 3000000, dispatch_generated, adjust_generated, |value| *value as u64, "direct", ); compare( "scalar_propagated", &[21], 3000000, dispatch_generated, propagated_reference, |value| *value as u64, ); compare( "scalar_helper", &[21], 3000000, dispatch_generated, helper_reference, |value| *value as u64, ); compare( "scalar_early_helper", &[21], 3000000, dispatch_generated, early_helper_reference, |value| *value as u64, ); compare( "scalar_independent_helper", &[21], 3000000, dispatch_generated, independent_helper_reference, |value| *value as u64, ); compare( "scalar_propagated_helper", &[21], 3000000, dispatch_generated, propagated_helper_reference, |value| *value as u64, ); compare( "scalar_batch", &values, 30000, batch_generated, batch_reference, |value| *value as u64, ); }