// Reproducible native benchmark for the public APCI codec path.
///|
pub struct BenchmarkResult {
operations : Int
successful : Int
elapsed_us : Double
} derive(Debug, Eq)
///|
pub fn BenchmarkResult::operations(self : BenchmarkResult) -> Int {
self.operations
}
///|
pub fn BenchmarkResult::successful(self : BenchmarkResult) -> Int {
self.successful
}
///|
pub fn BenchmarkResult::elapsed_us(self : BenchmarkResult) -> Double {
self.elapsed_us
}
///|
pub fn BenchmarkResult::operations_per_second(self : BenchmarkResult) -> Double {
if self.elapsed_us <= 0.0 {
0.0
} else {
self.successful.to_double() * 1000000.0 / self.elapsed_us
}
}
///|
pub fn BenchmarkResult::summary(self : BenchmarkResult) -> String {
"operations=" +
self.operations.to_string() +
", successful=" +
self.successful.to_string() +
", elapsed_us=" +
self.elapsed_us.to_string() +
", operations_per_second=" +
self.operations_per_second().to_string()
}
///|
pub fn run_apci_benchmark(iterations : Int) -> BenchmarkResult {
let count = if iterations < 0 { 0 } else { iterations }
let start = @bench.monotonic_clock_start()
let mut successful = 0
for i = 0; i < count; i = i + 1 {
let frame = @apdu.APDU::make_s(i % 32768)
let bytes = @apdu.encode_apdu(frame)
match @apdu.parse_apdu(bytes) {
Ok(_) => successful = successful + 1
Err(_) => ()
}
}
{
operations: count,
successful,
elapsed_us: @bench.monotonic_clock_end(start),
}
}
///|
test "benchmark reports successful codec operations" {
let result = run_apci_benchmark(32)
assert_eq(result.operations(), 32)
assert_eq(result.successful(), 32)
assert_true(result.elapsed_us() >= 0.0)
assert_true(result.summary().contains("operations_per_second="))
}