119 lines
3.5 KiB
Rust
119 lines
3.5 KiB
Rust
fn integer_reference(value: i64) -> Result<i64, Fault> {
|
|
let failure = &FaultInfo {
|
|
source: "reference",
|
|
line: 1,
|
|
column: 1,
|
|
message: "integer arithmetic fault",
|
|
};
|
|
value
|
|
.checked_mul(3)
|
|
.ok_or(failure)?
|
|
.checked_add(7)
|
|
.ok_or(failure)?
|
|
.checked_div(2)
|
|
.ok_or(failure)
|
|
}
|
|
|
|
fn list_reference(values: &[i64]) -> Result<i64, Fault> {
|
|
let failure = &FaultInfo {
|
|
source: "reference",
|
|
line: 1,
|
|
column: 1,
|
|
message: "integer overflow",
|
|
};
|
|
values
|
|
.iter()
|
|
.try_fold(0i64, |sum, value| sum.checked_add(*value))
|
|
.ok_or(failure)
|
|
}
|
|
|
|
fn text_reference(first: &str, second: &str) -> Result<String, Fault> {
|
|
let mut result = String::with_capacity(first.len() + second.len());
|
|
result.push_str(first);
|
|
result.push_str(second);
|
|
Ok(result)
|
|
}
|
|
|
|
fn sample(
|
|
name: &str,
|
|
sample: usize,
|
|
implementation: &str,
|
|
count: usize,
|
|
mut operation: impl FnMut(usize) -> usize,
|
|
) {
|
|
let start = Instant::now();
|
|
let mut checksum = 0usize;
|
|
for position in 0..count {
|
|
checksum = checksum.wrapping_add(black_box(operation(black_box(position))));
|
|
}
|
|
println!(
|
|
"{name},{sample},{implementation},{},{checksum}",
|
|
start.elapsed().as_nanos()
|
|
);
|
|
}
|
|
|
|
fn main() {
|
|
let values: Vec<i64> = (0..1024)
|
|
.map(|position| (position * 37 % 100) as i64)
|
|
.collect();
|
|
let text = "雪山远处有树林,近处有人撑伞。".repeat(4);
|
|
for value in [i64::MIN, -123, -1, 0, 100, i64::MAX] {
|
|
assert_eq!(
|
|
GENERATED_INTEGER(value).map_err(|_| ()),
|
|
integer_reference(value).map_err(|_| ())
|
|
);
|
|
}
|
|
assert_eq!(
|
|
GENERATED_LIST(&values).unwrap(),
|
|
list_reference(&values).unwrap()
|
|
);
|
|
assert!(GENERATED_LIST(&[i64::MAX, 1]).is_err());
|
|
assert!(list_reference(&[i64::MAX, 1]).is_err());
|
|
assert_eq!(
|
|
GENERATED_TEXT(&text, &text).unwrap(),
|
|
text_reference(&text, &text).unwrap()
|
|
);
|
|
println!("case,sample,implementation,elapsed_ns,checksum");
|
|
// 求和两侧共用计时函数,保留同函数 control,避免把调用端布局计入生成器差距。
|
|
compare(
|
|
"list_sum_1024",
|
|
&values,
|
|
40_000,
|
|
GENERATED_LIST,
|
|
list_reference,
|
|
|value| *value as u64,
|
|
);
|
|
for iteration in 0..9 {
|
|
for generated in if iteration % 2 == 0 {
|
|
[true, false]
|
|
} else {
|
|
[false, true]
|
|
} {
|
|
let implementation = if generated { "dever" } else { "rust" };
|
|
if generated {
|
|
sample(
|
|
"checked_int",
|
|
iteration,
|
|
implementation,
|
|
2_000_000,
|
|
|position| GENERATED_INTEGER(position as i64).unwrap() as usize,
|
|
);
|
|
sample("text_join", iteration, implementation, 300_000, |_| {
|
|
black_box(GENERATED_TEXT(black_box(&text), black_box(&text)).unwrap()).len()
|
|
});
|
|
} else {
|
|
sample(
|
|
"checked_int",
|
|
iteration,
|
|
implementation,
|
|
2_000_000,
|
|
|position| integer_reference(position as i64).unwrap() as usize,
|
|
);
|
|
sample("text_join", iteration, implementation, 300_000, |_| {
|
|
black_box(text_reference(black_box(&text), black_box(&text)).unwrap()).len()
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|