Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,3 @@
|
||||
long cmd run = app.run
|
||||
|
||||
long cmd continuous = app.continuous
|
||||
@@ -0,0 +1,39 @@
|
||||
type InputResult {
|
||||
Parsed(value: Decimal)
|
||||
error Invalid
|
||||
}
|
||||
|
||||
type State {
|
||||
total: Decimal
|
||||
factor: Decimal
|
||||
}
|
||||
|
||||
type Sample {
|
||||
elapsed_ns: Int
|
||||
checksum: Text
|
||||
}
|
||||
|
||||
parsed(value: Decimal) (result: Decimal) { result = value }
|
||||
parsed(value: null) (result: Decimal) { fail(InputResult.Invalid) }
|
||||
|
||||
step(value: Int, state: State) (next: State) {
|
||||
next = State {
|
||||
total = state.total + decimal.fromInt(value) * state.factor
|
||||
factor = state.factor
|
||||
}
|
||||
}
|
||||
|
||||
run(ticks: Text, initial: Text, factor: Text) (sample: Sample) {
|
||||
bytes = dever.bytes.fromText(ticks)
|
||||
state = State { total = parsed(decimal.parse(initial))
|
||||
factor = parsed(decimal.parse(factor)) }
|
||||
begin = dever.time.monotonicNanos()
|
||||
final = reduce(step, bytes, state)
|
||||
end = dever.time.monotonicNanos()
|
||||
sample = Sample { elapsed_ns = end - begin
|
||||
checksum = decimal.toText(final.total) }
|
||||
}
|
||||
|
||||
continuous(ticks: Text, initial: Text, factor: Text) (samples: List<Sample>) {
|
||||
samples = [run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor), run(ticks, initial, factor)]
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
use dec::{Context, Decimal128, Rounding};
|
||||
use dever_runtime::number::DecimalValue;
|
||||
use std::hint::black_box;
|
||||
use std::time::Instant;
|
||||
|
||||
fn finite(context: &Context<Decimal128>, value: Decimal128) -> Decimal128 {
|
||||
let status = context.status();
|
||||
assert!(!status.division_by_zero() && !status.division_undefined());
|
||||
assert!(!status.overflow() && !status.underflow());
|
||||
assert!(!status.invalid_operation() && !status.invalid_context() && value.is_finite());
|
||||
value
|
||||
}
|
||||
|
||||
fn measure(mode: &str, ticks: &str, initial: &str, factor: &str) -> serde_json::Value {
|
||||
let bytes = black_box(ticks.as_bytes());
|
||||
let (checksum, elapsed) = if mode == "runtime" {
|
||||
let mut total = DecimalValue::parse(initial).expect("initial");
|
||||
let factor = DecimalValue::parse(factor).expect("factor");
|
||||
let begin = Instant::now();
|
||||
for value in bytes {
|
||||
let product = DecimalValue::from_int(i64::from(*value))
|
||||
.checked_mul(factor)
|
||||
.expect("multiply");
|
||||
total = total.checked_add(product).expect("add");
|
||||
}
|
||||
black_box(total);
|
||||
let elapsed = begin.elapsed();
|
||||
(total.to_string(), elapsed)
|
||||
} else {
|
||||
assert_eq!(mode, "decimal128");
|
||||
let mut context = Context::<Decimal128>::default();
|
||||
let mut total = context.parse(initial).expect("initial");
|
||||
assert!(!context.status().inexact() && total.is_finite());
|
||||
context.clear_status();
|
||||
let factor = context.parse(factor).expect("factor");
|
||||
assert!(!context.status().inexact() && factor.is_finite());
|
||||
context.set_rounding(Rounding::HalfEven);
|
||||
let begin = Instant::now();
|
||||
for value in bytes {
|
||||
let item = Decimal128::from(i64::from(*value));
|
||||
context.clear_status();
|
||||
let product = context.mul(item, factor);
|
||||
let product = finite(&context, product);
|
||||
context.clear_status();
|
||||
let sum = context.add(total, product);
|
||||
total = finite(&context, sum);
|
||||
}
|
||||
black_box(total);
|
||||
let elapsed = begin.elapsed();
|
||||
(context.reduce(total).to_string(), elapsed)
|
||||
};
|
||||
serde_json::json!({"checksum": checksum, "elapsed_ns": elapsed.as_nanos()})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let arguments = std::env::args().collect::<Vec<_>>();
|
||||
let input: serde_json::Value = serde_json::from_str(&arguments[3]).expect("input object");
|
||||
let ticks = input["ticks"].as_str().expect("ticks");
|
||||
let initial = input["initial"].as_str().expect("initial");
|
||||
let factor = input["factor"].as_str().expect("factor");
|
||||
let output = match arguments[2].as_str() {
|
||||
"run" => measure(&arguments[1], ticks, initial, factor),
|
||||
"continuous" => serde_json::Value::Array(
|
||||
(0..10)
|
||||
.map(|_| measure(&arguments[1], ticks, initial, factor))
|
||||
.collect(),
|
||||
),
|
||||
_ => panic!("unknown measurement"),
|
||||
};
|
||||
println!("{output}");
|
||||
}
|
||||
Reference in new issue
Block a user