fn fault() -> Fault { &FaultInfo { message: "integer arithmetic fault", source: "reference.dever", line: 1, column: 1, } } fn integer_reference(values: &[i64]) -> Result { values .first() .copied() .unwrap_or(0) .checked_add(1) .ok_or_else(fault) } fn integer_generated(values: &[i64]) -> Result { GENERATED_INTEGER(values.first().copied().unwrap_or(0)) } fn map_reference(values: &[i64]) -> Result, Fault> { let mut output = Vec::with_capacity(values.len()); for value in values { output.push(value.checked_add(1).ok_or_else(fault)?); } Ok(output) } fn fold_reference(values: &[i64]) -> Result { let mut state = 0i64; for value in values { state = state.checked_add(*value).ok_or_else(fault)?; } Ok(state) } fn text_reference(values: &[String]) -> Result { let value = values.first().map(String::as_str).unwrap_or(""); let mut result = String::with_capacity(value.len() + "新".len()); result.push_str(value); result.push_str("新"); Ok(result) } fn text_generated(values: &[String]) -> Result { GENERATED_TEXT(values.first().map(String::as_str).unwrap_or("")) } fn text_direct_generated(values: &[String]) -> Result { GENERATED_APPEND(values.first().map(String::as_str).unwrap_or("")) } fn append_reference(value: &str) -> Result { let mut result = String::with_capacity(value.len() + "新".len()); result.push_str(value); result.push_str("新"); Ok(result) } fn text_helper_reference(values: &[String]) -> Result { append_reference(values.first().map(String::as_str).unwrap_or("")) } fn rows_reference(values: &[ROW_TYPE]) -> Result, Fault> { let mut result = Vec::with_capacity(values.len()); for value in values { let mut name = String::with_capacity(value.field0.len() + "新".len()); name.push_str(&value.field0); name.push_str("新"); result.push(ROW_TYPE { field0: name, field1: value.field1.checked_add(1).ok_or_else(fault)?, }); } Ok(result) } fn capture_reference(values: &[i64]) -> Result, Fault> { let mut result = Vec::with_capacity(values.len()); for value in values { result.push(if *value < 0 { RESULT_TYPE::Variant1(PROBLEM_TYPE::Variant0(*value)) } else { RESULT_TYPE::Variant0(*value) }); } Ok(result) } fn capture_generated(values: &[i64]) -> Result, Fault> { let mut result = Vec::with_capacity(values.len()); for value in values { result.push(GENERATED_CAPTURE(*value)?); } Ok(result) } // 观察部分构造后失败的清理,成功返回的 bool 保持共享计时/内存入口不变。 fn map_failed_generated(values: &[i64]) -> Result { Ok(GENERATED_MAP(values).is_err()) } fn map_failed_reference(values: &[i64]) -> Result { Ok(map_reference(values).is_err()) } fn rows_failed_generated(values: &[ROW_TYPE]) -> Result { Ok(GENERATED_ROWS(values).is_err()) } fn rows_failed_reference(values: &[ROW_TYPE]) -> Result { Ok(rows_reference(values).is_err()) } fn main() { let values: Vec = (0..1024).map(|value| (value * 17) % 1000 - 1).collect(); let failures: Vec = (0..128).map(|value| (value % 8) - 1).collect(); let rows: Vec<_> = (0..64) .map(|index| ROW_TYPE { field0: "雪山树林".repeat(4), field1: index, }) .collect(); let texts = ["雪山树林".repeat(16)]; eprintln!( "text_forward_equals_direct_address={}", std::ptr::fn_addr_eq( text_generated as fn(&[String]) -> Result, text_direct_generated as fn(&[String]) -> Result ) ); for values in [&[i64::MAX][..], &[i64::MAX, 1][..], &[i64::MIN, -1][..]] { assert_eq!( integer_generated(values).map_err(|_| ()), integer_reference(values).map_err(|_| ()) ); assert_eq!( GENERATED_MAP(values).map_err(|_| ()), map_reference(values).map_err(|_| ()) ); assert_eq!( GENERATED_FOLD(values).map_err(|_| ()), fold_reference(values).map_err(|_| ()) ); assert_eq!( capture_generated(values).unwrap(), capture_reference(values).unwrap() ); } println!("case,sample,implementation,elapsed_ns,checksum"); compare( "handler_integer", &[41], 3000000, integer_generated, integer_reference, |value| *value as u64, ); compare( "handler_map", &values, 20000, GENERATED_MAP, map_reference, |value| value.len() as u64, ); compare( "handler_fold", &values, 30000, GENERATED_FOLD, fold_reference, |value| *value as u64, ); compare( "handler_text", &texts, 300000, text_generated, text_reference, |value| value.len() as u64, ); compare_borrowed( "handler_text", &texts, 300000, text_generated, text_reference, |value| value.len() as u64, ); compare( "handler_text_helper", &texts, 300000, text_generated, text_helper_reference, |value| value.len() as u64, ); compare_named( "handler_text_direct", &texts, 300000, text_generated, text_direct_generated, |value| value.len() as u64, "direct", ); compare( "handler_record", &rows, 5000, GENERATED_ROWS, rows_reference, |value| value.len() as u64, ); compare( "handler_capture", &failures, 30000, capture_generated, capture_reference, |value| value.len() as u64, ); compare( "handler_map_failure", &[1, 2, i64::MAX], 100000, map_failed_generated, map_failed_reference, |value| u64::from(*value), ); let mut failed_rows = rows; failed_rows.last_mut().unwrap().field1 = i64::MAX; compare( "handler_record_failure", &failed_rows, 5000, rows_failed_generated, rows_failed_reference, |value| u64::from(*value), ); }