259 lines
7.5 KiB
Rust
259 lines
7.5 KiB
Rust
fn chain_reference(values: &[String]) -> Result<String, Fault> {
|
|
let value = values.first().map(String::as_str).unwrap_or("");
|
|
let mut output = String::with_capacity(value.len() + value.len() + 3);
|
|
output.push('[');
|
|
output.push_str(value);
|
|
output.push(':');
|
|
output.push_str(value);
|
|
output.push(']');
|
|
Ok(output)
|
|
}
|
|
|
|
fn chain_generated(values: &[String]) -> Result<String, Fault> {
|
|
GENERATED_CHAIN(values.first().map(String::as_str).unwrap_or(""))
|
|
}
|
|
|
|
// 与 Dever 的 str 函数边界一致;原切片入口参照仍保留。
|
|
fn chain_native(value: &str) -> Result<String, Fault> {
|
|
let mut output = String::with_capacity(value.len() + value.len() + 3);
|
|
output.push('[');
|
|
output.push_str(value);
|
|
output.push(':');
|
|
output.push_str(value);
|
|
output.push(']');
|
|
Ok(output)
|
|
}
|
|
|
|
fn chain_boundary(values: &[String]) -> Result<String, Fault> {
|
|
chain_native(values.first().map(String::as_str).unwrap_or(""))
|
|
}
|
|
|
|
fn pair_reference(values: &[String]) -> Result<String, Fault> {
|
|
let value = values.first().map(String::as_str).unwrap_or("");
|
|
let mut output = String::with_capacity(value.len() + value.len());
|
|
output.push_str(value);
|
|
output.push_str(value);
|
|
Ok(output)
|
|
}
|
|
|
|
fn pair_generated(values: &[String]) -> Result<String, Fault> {
|
|
GENERATED_PAIR(values.first().map(String::as_str).unwrap_or(""))
|
|
}
|
|
|
|
fn temporary_generated(values: &[String]) -> Result<String, Fault> {
|
|
GENERATED_TEMPORARY(values.first().map(String::as_str).unwrap_or(""))
|
|
}
|
|
|
|
fn temporary_reference(values: &[String]) -> Result<String, Fault> {
|
|
let value = values.first().map(String::as_str).unwrap_or("");
|
|
let mut output = String::with_capacity(value.len() + "后".len());
|
|
output.push_str(value);
|
|
output.push_str("后");
|
|
Ok(output)
|
|
}
|
|
|
|
fn forwarded_generated(values: &[String]) -> Result<String, Fault> {
|
|
GENERATED_FORWARDED(values.first().map(String::as_str).unwrap_or(""))
|
|
}
|
|
|
|
fn contains_reference(values: &[SEARCH_PAIR]) -> Result<i64, Fault> {
|
|
let mut total = 0i64;
|
|
for pair in values {
|
|
total = total
|
|
.checked_add(if pair.field0.contains(pair.field1.as_str()) {
|
|
120
|
|
} else {
|
|
0
|
|
})
|
|
.ok_or(
|
|
const {
|
|
&FaultInfo {
|
|
message: "integer arithmetic fault",
|
|
source: "reference",
|
|
line: 1,
|
|
column: 1,
|
|
}
|
|
},
|
|
)?;
|
|
}
|
|
Ok(total)
|
|
}
|
|
|
|
fn concatenate_text_reference(values: &[String]) -> Result<String, Fault> {
|
|
let mut output = String::new();
|
|
for value in values {
|
|
output.push_str(value);
|
|
}
|
|
Ok(output)
|
|
}
|
|
|
|
fn concatenate_bytes_reference(
|
|
values: &[dever_runtime::Bytes],
|
|
) -> Result<dever_runtime::Bytes, Fault> {
|
|
let mut output = Vec::new();
|
|
for value in values {
|
|
output.extend_from_slice(value);
|
|
}
|
|
Ok(output.into())
|
|
}
|
|
|
|
fn main() {
|
|
println!("case,sample,implementation,elapsed_ns,checksum");
|
|
for count in [8, 256, 4096] {
|
|
let values = vec!["雪山".to_owned(); count];
|
|
compare(
|
|
&format!("list_contains_{count}"),
|
|
&values,
|
|
2000,
|
|
list_contains_generated,
|
|
list_contains_reference,
|
|
|found| u64::from(*found),
|
|
);
|
|
}
|
|
// 双方使用同一批 String;独立 Rust 实现只调用标准库,排除分配布局和内置时钟差异。
|
|
for count in [512, 1024, 2048, 4096] {
|
|
let values: Vec<_> = (0..count)
|
|
.map(|_| {
|
|
let text = "compare-value-120".to_owned();
|
|
let pattern = text.to_uppercase().to_lowercase();
|
|
SEARCH_PAIR {
|
|
field0: text,
|
|
field1: pattern,
|
|
}
|
|
})
|
|
.collect();
|
|
compare(
|
|
&format!("text_contains_{count}"),
|
|
&values,
|
|
1000,
|
|
GENERATED_CONTAINS,
|
|
contains_reference,
|
|
|value| *value as u64,
|
|
);
|
|
}
|
|
let values: Vec<_> = [
|
|
("雪山🙂", "山"),
|
|
("abc", "z"),
|
|
("abc", ""),
|
|
("", "x"),
|
|
("", ""),
|
|
]
|
|
.into_iter()
|
|
.map(|(text, pattern)| SEARCH_PAIR {
|
|
field0: text.into(),
|
|
field1: pattern.into(),
|
|
})
|
|
.collect();
|
|
assert_eq!(GENERATED_CONTAINS(&values).unwrap(), 360);
|
|
assert_eq!(contains_reference(&values).unwrap(), 360);
|
|
for count in [512, 2048, 8192, 32768] {
|
|
let texts = vec!["x".to_owned(); count];
|
|
let bytes = (0..count)
|
|
.map(|_| dever_runtime::Bytes::from(vec![b'x']))
|
|
.collect::<Vec<_>>();
|
|
compare(
|
|
&format!("text_concat_{count}"),
|
|
&texts,
|
|
200,
|
|
GENERATED_TEXT_CONCAT,
|
|
concatenate_text_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
compare(
|
|
&format!("bytes_concat_{count}"),
|
|
&bytes,
|
|
200,
|
|
GENERATED_BYTES_CONCAT,
|
|
concatenate_bytes_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
}
|
|
for (name, value, count) in [
|
|
("text_chain_empty", String::new(), 300000),
|
|
("text_chain_small", "雪山".repeat(2), 300000),
|
|
("text_chain_large", "雪山".repeat(1024), 30000),
|
|
] {
|
|
let values = [value];
|
|
compare(
|
|
name,
|
|
&values,
|
|
count,
|
|
chain_generated,
|
|
chain_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
compare(
|
|
&format!("{name}_boundary"),
|
|
&values,
|
|
count,
|
|
chain_generated,
|
|
chain_boundary,
|
|
|value| value.len() as u64,
|
|
);
|
|
compare_borrowed(
|
|
name,
|
|
&values,
|
|
count,
|
|
chain_generated,
|
|
chain_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
}
|
|
compare(
|
|
"text_pair",
|
|
&["雪山".repeat(32)],
|
|
300000,
|
|
pair_generated,
|
|
pair_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
for (name, value, count) in [
|
|
("text_temporary_empty", String::new(), 300000),
|
|
("text_temporary_small", "雪山".repeat(2), 300000),
|
|
("text_temporary_medium", "雪山".repeat(32), 300000),
|
|
("text_temporary_large", "雪山".repeat(1024), 30000),
|
|
] {
|
|
let values = [value];
|
|
compare(
|
|
name,
|
|
&values,
|
|
count,
|
|
temporary_generated,
|
|
temporary_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
compare(
|
|
&format!("{name}_forwarded"),
|
|
&values,
|
|
count,
|
|
forwarded_generated,
|
|
temporary_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
compare_borrowed(
|
|
name,
|
|
&values,
|
|
count,
|
|
temporary_generated,
|
|
temporary_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
compare_borrowed(
|
|
&format!("{name}_forwarded"),
|
|
&values,
|
|
count,
|
|
forwarded_generated,
|
|
temporary_reference,
|
|
|value| value.len() as u64,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn list_contains_generated(values: &[String]) -> Result<bool, Fault> {
|
|
GENERATED_LIST_CONTAINS(values, "absent")
|
|
}
|
|
|
|
fn list_contains_reference(values: &[String]) -> Result<bool, Fault> {
|
|
Ok(values.iter().any(|item| item.as_str() == "absent"))
|
|
}
|