#![allow(dead_code)]
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use pitwall::adapters::FrameAdapter;
use pitwall::types::FramePacket;
use pitwall::{DynamicFrame, PitwallFrame, VariableSchema};
use std::hint::black_box;
use std::sync::Arc;
#[derive(PitwallFrame, Debug, Clone)]
struct SmallFrame {
#[field_name = "Speed"]
speed: f32,
#[field_name = "Gear"]
gear: i32,
#[field_name = "RPM"]
rpm: f32,
#[field_name = "Throttle"]
throttle: f32,
#[field_name = "Brake"]
brake: f32,
}
#[derive(PitwallFrame, Debug, Clone)]
struct MediumFrame {
#[field_name = "Speed"]
speed: f32,
#[field_name = "Gear"]
gear: i32,
#[field_name = "RPM"]
rpm: f32,
#[field_name = "Throttle"]
throttle: f32,
#[field_name = "Brake"]
brake: f32,
#[field_name = "Clutch"]
clutch: f32,
#[field_name = "SteeringWheelAngle"]
steering: f32,
#[field_name = "Lap"]
lap: i32,
#[field_name = "LapDist"]
lap_dist: f32,
#[field_name = "LapDistPct"]
lap_dist_pct: f32,
#[field_name = "LapCurrentLapTime"]
current_lap_time: f32,
#[field_name = "LapLastLapTime"]
last_lap_time: f32,
#[field_name = "LapBestLapTime"]
best_lap_time: f32,
#[field_name = "SessionTime"]
session_time: f64,
#[field_name = "SessionTick"]
session_tick: i32,
#[field_name = "SessionNum"]
session_num: i32,
#[field_name = "SessionState"]
session_state: i32,
#[field_name = "VelocityX"]
velocity_x: f32,
#[field_name = "VelocityY"]
velocity_y: f32,
#[field_name = "VelocityZ"]
velocity_z: f32,
}
#[derive(PitwallFrame, Debug, Clone)]
struct LargeFrame {
#[field_name = "Speed"]
speed: f32,
#[field_name = "Gear"]
gear: i32,
#[field_name = "RPM"]
rpm: f32,
#[field_name = "Throttle"]
throttle: f32,
#[field_name = "Brake"]
brake: f32,
#[field_name = "Clutch"]
clutch: f32,
#[field_name = "SteeringWheelAngle"]
steering: f32,
#[field_name = "Lap"]
lap: i32,
#[field_name = "LapDist"]
lap_dist: f32,
#[field_name = "LapDistPct"]
lap_dist_pct: f32,
#[field_name = "LapCurrentLapTime"]
current_lap_time: f32,
#[field_name = "LapLastLapTime"]
last_lap_time: f32,
#[field_name = "LapBestLapTime"]
best_lap_time: f32,
#[field_name = "SessionTime"]
session_time: f64,
#[field_name = "SessionTick"]
session_tick: i32,
#[field_name = "SessionNum"]
session_num: i32,
#[field_name = "SessionState"]
session_state: i32,
#[field_name = "VelocityX"]
velocity_x: f32,
#[field_name = "VelocityY"]
velocity_y: f32,
#[field_name = "VelocityZ"]
velocity_z: f32,
#[field_name = "YawRate"]
yaw_rate: f32,
#[field_name = "Pitch"]
pitch: f32,
#[field_name = "Roll"]
roll: f32,
#[field_name = "PitchRate"]
pitch_rate: f32,
#[field_name = "RollRate"]
roll_rate: f32,
#[field_name = "SteeringWheelTorque"]
steering_torque: f32,
#[field_name = "FuelLevel"]
fuel: Option<f32>,
#[field_name = "FuelLevelPct"]
fuel_pct: Option<f32>,
#[field_name = "FuelUsePerHour"]
fuel_use: Option<f32>,
#[field_name = "WaterTemp"]
water_temp: Option<f32>,
#[field_name = "OilTemp"]
oil_temp: Option<f32>,
#[field_name = "OilPress"]
oil_press: Option<f32>,
#[field_name = "LFtempCL"]
lf_temp_cl: Option<f32>,
#[field_name = "LFtempCM"]
lf_temp_cm: Option<f32>,
#[field_name = "LFtempCR"]
lf_temp_cr: Option<f32>,
#[field_name = "RFtempCL"]
rf_temp_cl: Option<f32>,
#[field_name = "RFtempCM"]
rf_temp_cm: Option<f32>,
#[field_name = "RFtempCR"]
rf_temp_cr: Option<f32>,
#[field_name = "LRtempCL"]
lr_temp_cl: Option<f32>,
#[field_name = "LRtempCM"]
lr_temp_cm: Option<f32>,
#[field_name = "LRtempCR"]
lr_temp_cr: Option<f32>,
#[field_name = "RRtempCL"]
rr_temp_cl: Option<f32>,
#[field_name = "RRtempCM"]
rr_temp_cm: Option<f32>,
#[field_name = "RRtempCR"]
rr_temp_cr: Option<f32>,
#[field_name = "SessionTimeRemain"]
time_remain: Option<f64>,
#[field_name = "ReplayFrameNum"]
replay_frame: Option<i32>,
#[field_name = "IsReplayPlaying"]
is_replay: Option<bool>,
}
#[derive(PitwallFrame, Debug, Clone)]
struct OptionalFieldsFrame {
#[field_name = "Speed"]
speed: f32,
#[field_name = "Gear"]
gear: Option<i32>,
#[field_name = "FuelLevel"]
fuel: Option<f32>,
#[field_name = "FuelLevelPct"]
fuel_pct: Option<f32>,
#[field_name = "WaterTemp"]
water_temp: Option<f32>,
}
fn get_test_frame() -> (FramePacket, Arc<VariableSchema>) {
use pitwall::IbtReader;
use pitwall::test_utils::get_smallest_ibt_test_file;
let ibt_file = get_smallest_ibt_test_file().expect("No IBT test files found");
let mut reader = IbtReader::open(&ibt_file).expect("Failed to open IBT file");
let schema = Arc::new(reader.variables().clone());
let (data, tick, session_version) =
reader.read_next_frame().expect("Failed to read frame").expect("No frames in IBT");
let packet = FramePacket::new(data, tick, session_version, Arc::clone(&schema));
(packet, schema)
}
fn bench_dynamic_frame(c: &mut Criterion) {
let (packet, schema) = get_test_frame();
let validation =
DynamicFrame::validate_schema(&schema).expect("DynamicFrame validation failed");
let mut group = c.benchmark_group("dynamic_frame");
group.bench_function("adapt", |b| {
b.iter(|| {
let frame = DynamicFrame::adapt(black_box(&packet), black_box(&validation));
black_box(frame)
})
});
let frame = DynamicFrame::adapt(&packet, &validation);
group.bench_function("scalar_field_access", |b| {
b.iter(|| {
let speed = black_box(frame.f32("Speed"));
black_box(speed)
})
});
group.bench_function("array_field_access", |b| {
b.iter(|| {
let lap_dist: Option<Vec<f32>> = black_box(frame.get("CarIdxLapDistPct"));
black_box(lap_dist)
})
});
group.finish();
}
fn bench_derived_adapters(c: &mut Criterion) {
let (packet, schema) = get_test_frame();
let mut group = c.benchmark_group("derived_adapters");
if let Ok(validation) = SmallFrame::validate_schema(&schema) {
group.bench_function(BenchmarkId::new("small_frame", "5_fields"), |b| {
b.iter(|| {
let frame = SmallFrame::adapt(black_box(&packet), black_box(&validation));
black_box(frame)
})
});
}
if let Ok(validation) = MediumFrame::validate_schema(&schema) {
group.bench_function(BenchmarkId::new("medium_frame", "20_fields"), |b| {
b.iter(|| {
let frame = MediumFrame::adapt(black_box(&packet), black_box(&validation));
black_box(frame)
})
});
}
if let Ok(validation) = LargeFrame::validate_schema(&schema) {
group.bench_function(BenchmarkId::new("large_frame", "50_fields"), |b| {
b.iter(|| {
let frame = LargeFrame::adapt(black_box(&packet), black_box(&validation));
black_box(frame)
})
});
}
group.finish();
}
fn bench_optional_fields(c: &mut Criterion) {
let (packet, schema) = get_test_frame();
let mut group = c.benchmark_group("optional_fields");
if let Ok(validation) = OptionalFieldsFrame::validate_schema(&schema) {
group.bench_function("optional_fields_frame", |b| {
b.iter(|| {
let frame = OptionalFieldsFrame::adapt(black_box(&packet), black_box(&validation));
black_box(frame)
})
});
}
group.finish();
}
criterion_group!(benches, bench_dynamic_frame, bench_derived_adapters, bench_optional_fields);
criterion_main!(benches);