Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,203 @@
|
||||
// 保留直接 Rust 参照,分别观察值参数、借用参数和 Result 对循环优化的影响。
|
||||
|
||||
fn generated(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
total += GENERATED_FLOAT(value)?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn reference(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
total += match value {
|
||||
None => -1,
|
||||
Some(value) if *value == 1.0 => 1,
|
||||
Some(value) if *value == 0.0 => 0,
|
||||
Some(_) => 2,
|
||||
};
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn generated_batch(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
GENERATED_FLOAT_TOTAL(values)
|
||||
}
|
||||
|
||||
fn reference_batch(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
let projected = match value {
|
||||
None => -1,
|
||||
Some(value) if *value == 1.0 => 1,
|
||||
Some(value) if *value == 0.0 => 0,
|
||||
Some(_) => 2,
|
||||
};
|
||||
total = total.checked_add(projected).ok_or(&FaultInfo {
|
||||
message: "integer overflow",
|
||||
source: "Rust reference",
|
||||
line: 0,
|
||||
column: 0,
|
||||
})?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn classify(value: Option<f64>) -> i64 {
|
||||
match value {
|
||||
None => -1,
|
||||
Some(value) if value == 1.0 => 1,
|
||||
Some(value) if value == 0.0 => 0,
|
||||
Some(_) => 2,
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_result(value: Option<f64>) -> Result<i64, Fault> {
|
||||
Ok(classify(value))
|
||||
}
|
||||
|
||||
fn classify_borrowed(value: &Option<f64>) -> i64 {
|
||||
match value {
|
||||
None => -1,
|
||||
Some(value) if *value == 1.0 => 1,
|
||||
Some(value) if *value == 0.0 => 0,
|
||||
Some(_) => 2,
|
||||
}
|
||||
}
|
||||
|
||||
fn value_helper(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
total += classify(*value);
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn result_helper(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
total += classify_result(*value)?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn borrowed_helper(values: &[Option<f64>]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
total += classify_borrowed(value);
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let special = [
|
||||
None,
|
||||
Some(0.0),
|
||||
Some(-0.0),
|
||||
Some(1.0),
|
||||
Some(-1.0),
|
||||
Some(f64::NAN),
|
||||
Some(f64::INFINITY),
|
||||
Some(f64::NEG_INFINITY),
|
||||
];
|
||||
let values = (0..256)
|
||||
.map(|index| special[index % special.len()])
|
||||
.collect::<Vec<_>>();
|
||||
let mut state = 0x123456789abcdef0u64;
|
||||
let mixed = (0..256)
|
||||
.map(|index| {
|
||||
state = state.wrapping_mul(6364136223846793005).wrapping_add(1);
|
||||
if index % 3 == 0 {
|
||||
Some(f64::from_bits(state))
|
||||
} else {
|
||||
special[((state >> 32) as usize) % special.len()]
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let references = [
|
||||
(
|
||||
"direct",
|
||||
reference as fn(&[Option<f64>]) -> Result<i64, Fault>,
|
||||
),
|
||||
("value", value_helper),
|
||||
("result", result_helper),
|
||||
("borrowed", borrowed_helper),
|
||||
];
|
||||
for (name, operation) in references {
|
||||
for value in values.iter().chain(&mixed) {
|
||||
assert_eq!(generated(&[*value]).unwrap(), operation(&[*value]).unwrap());
|
||||
}
|
||||
eprintln!(
|
||||
"{name}_equals_generated={}",
|
||||
std::ptr::fn_addr_eq(
|
||||
operation,
|
||||
generated as fn(&[Option<f64>]) -> Result<i64, Fault>
|
||||
)
|
||||
);
|
||||
}
|
||||
println!("case,sample,implementation,elapsed_ns,checksum");
|
||||
for (name, values) in [("float_batch", &values), ("float_batch_mixed", &mixed)] {
|
||||
compare(
|
||||
name,
|
||||
values,
|
||||
10000,
|
||||
generated_batch,
|
||||
reference_batch,
|
||||
|value| *value as u64,
|
||||
);
|
||||
}
|
||||
compare(
|
||||
"float_direct",
|
||||
&values,
|
||||
10000,
|
||||
generated,
|
||||
reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"float_mixed",
|
||||
&mixed,
|
||||
10000,
|
||||
generated,
|
||||
reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"float_value_helper",
|
||||
&values,
|
||||
10000,
|
||||
generated,
|
||||
value_helper,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"float_result_helper",
|
||||
&values,
|
||||
10000,
|
||||
generated,
|
||||
result_helper,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"float_borrowed_helper",
|
||||
&values,
|
||||
10000,
|
||||
generated,
|
||||
borrowed_helper,
|
||||
|value| *value as u64,
|
||||
);
|
||||
// 同一混合序列也经过各参照,避免把函数边界或布局差异归给 Dever。
|
||||
for (name, operation) in [
|
||||
(
|
||||
"float_mixed_value_helper",
|
||||
value_helper as fn(&[Option<f64>]) -> Result<i64, Fault>,
|
||||
),
|
||||
("float_mixed_result_helper", result_helper),
|
||||
("float_mixed_borrowed_helper", borrowed_helper),
|
||||
] {
|
||||
compare(name, &mixed, 10000, generated, operation, |value| {
|
||||
*value as u64
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user