Files
core/test/rust/performance/handler.rs
T
2026-11-03 03:32:07 +00:00

245 lines
6.5 KiB
Rust

fn fault() -> Fault {
&FaultInfo {
message: "integer arithmetic fault",
source: "reference.dever",
line: 1,
column: 1,
}
}
fn integer_reference(values: &[i64]) -> Result<i64, Fault> {
values
.first()
.copied()
.unwrap_or(0)
.checked_add(1)
.ok_or_else(fault)
}
fn integer_generated(values: &[i64]) -> Result<i64, Fault> {
GENERATED_INTEGER(values.first().copied().unwrap_or(0))
}
fn map_reference(values: &[i64]) -> Result<Vec<i64>, 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<i64, Fault> {
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<String, Fault> {
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<String, Fault> {
GENERATED_TEXT(values.first().map(String::as_str).unwrap_or(""))
}
fn text_direct_generated(values: &[String]) -> Result<String, Fault> {
GENERATED_APPEND(values.first().map(String::as_str).unwrap_or(""))
}
fn append_reference(value: &str) -> Result<String, Fault> {
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<String, Fault> {
append_reference(values.first().map(String::as_str).unwrap_or(""))
}
fn rows_reference(values: &[ROW_TYPE]) -> Result<Vec<ROW_TYPE>, 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<Vec<RESULT_TYPE>, 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<Vec<RESULT_TYPE>, 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<bool, Fault> {
Ok(GENERATED_MAP(values).is_err())
}
fn map_failed_reference(values: &[i64]) -> Result<bool, Fault> {
Ok(map_reference(values).is_err())
}
fn rows_failed_generated(values: &[ROW_TYPE]) -> Result<bool, Fault> {
Ok(GENERATED_ROWS(values).is_err())
}
fn rows_failed_reference(values: &[ROW_TYPE]) -> Result<bool, Fault> {
Ok(rows_reference(values).is_err())
}
fn main() {
let values: Vec<i64> = (0..1024).map(|value| (value * 17) % 1000 - 1).collect();
let failures: Vec<i64> = (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<String, Fault>,
text_direct_generated as fn(&[String]) -> Result<String, Fault>
)
);
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),
);
}