fn fault() -> Fault { &FaultInfo { message: "integer arithmetic fault", source: "reference.dever", line: 1, column: 1, } } fn map_reference(values: &[i64]) -> Result, Fault> { let mut output = Vec::with_capacity(values.len()); for value in values { output.push(value.checked_mul(2).ok_or_else(fault)?); } Ok(output) } fn filter_reference(values: &[i64]) -> Result, Fault> { let mut output = Vec::new(); for value in values { if *value > 0 { output.push(*value); } } Ok(output) } fn find_reference(values: &[i64]) -> Result, Fault> { Ok(values.iter().find(|value| **value > 997).copied()) } fn find_generated(values: &[i64]) -> Result, Fault> { GENERATED_FIND(values, 997) } fn sum_reference(values: &[i64]) -> Result { let mut total = 0i64; for value in values { let projected = value.checked_mul(2).ok_or_else(fault)?; total = total.checked_add(projected).ok_or_else(fault)?; } Ok(total) } 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 stop_reference(values: &[i64]) -> Result { let mut state = 0i64; for value in values { state = state.checked_add(*value).ok_or_else(fault)?; if state >= 3 { break; } } Ok(state) } fn rows_reference(values: &[ROW_TYPE]) -> Result, Fault> { let mut output = 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("新"); output.push(ROW_TYPE { field0: name, field1: value.field1.checked_add(1).ok_or_else(fault)?, }); } Ok(output) } fn main() { let values: Vec = (0..1024).map(|value| (value * 17) % 1000 - 1).collect(); let rows: Vec<_> = (0..64) .map(|index| ROW_TYPE { field0: "雪山树林".repeat(4), field1: index, }) .collect(); for values in [&[i64::MAX][..], &[i64::MAX / 2, 3][..], &[i64::MIN, -1][..]] { assert_eq!( GENERATED_MAP(values).map_err(|_| ()), map_reference(values).map_err(|_| ()) ); assert_eq!( GENERATED_SUM(values).map_err(|_| ()), sum_reference(values).map_err(|_| ()) ); assert_eq!( GENERATED_FOLD(values).map_err(|_| ()), fold_reference(values).map_err(|_| ()) ); assert_eq!( GENERATED_STOP(values).map_err(|_| ()), stop_reference(values).map_err(|_| ()) ); } println!("case,sample,implementation,elapsed_ns,checksum"); compare( "each_int", &values, 20000, GENERATED_MAP, map_reference, |value| value.len() as u64, ); compare( "filter_int", &values, 20000, GENERATED_FILTER, filter_reference, |value| value.len() as u64, ); compare( "find_int", &values, 50000, find_generated, find_reference, |value| value.unwrap_or(0) as u64, ); compare( "project_sum", &values, 30000, GENERATED_SUM, sum_reference, |value| *value as u64, ); compare( "reduce_int", &values, 30000, GENERATED_FOLD, fold_reference, |value| *value as u64, ); compare( "reduce_until_int", &values, 500000, GENERATED_STOP, stop_reference, |value| *value as u64, ); compare( "each_record", &rows, 5000, GENERATED_ROWS, rows_reference, |value| value.len() as u64, ); }