use criterion::{black_box, criterion_group, criterion_main, Criterion}; use lta_models::{bus::bus_arrival::NextBusRaw, prelude::*}; use mimalloc::MiMalloc; use time::macros::datetime; #[global_allocator] static GLOBAL: MiMalloc = MiMalloc; #[rustfmt::skip] mod de { use std::fmt::Debug; use lta_models::prelude::*; use lta_models::bus::bus_arrival::NextBusRaw; use serde::{Deserialize, Serialize}; pub fn generate_bench<'de, I, S, F>(input_fn: F) -> S where F: FnOnce() -> &'de str, I: Deserialize<'de> + Into, S: Serialize + Debug { let str_data = input_fn(); serde_json::from_str(str_data).map(|v: I| v.into()).unwrap() } macro_rules! gen { ($a:ty, $b:ty, $c:expr) => { generate_bench::<$a, $b, _>(|| include_str!($c)) }; } pub fn bike_parking() -> Vec { gen!(BikeParkingResp, _, "../dumped_data/bike_parking.json") } pub fn bus_arrival() -> BusArrivalResp { gen!(BusArrivalRespRaw, _, "../dumped_data/bus_arrival.json") } pub fn bus_routes() -> Vec { gen!(BusRouteResp, _, "../dumped_data/bus_route.json") } pub fn bus_service() -> Vec { gen!(BusServiceResp, _, "../dumped_data/bus_services.json") } pub fn bus_stops() -> Vec { gen!(BusStopsResp, _, "../dumped_data/bus_stops.json") } pub fn carpark_avail() -> Vec { gen!(CarparkAvailResp, _, "../dumped_data/carpark_avail.json") } pub fn erp_rates() -> Vec { gen!(ErpRatesResp, _, "../dumped_data/erp_rates.json") } pub fn faulty_traffic_lights() -> Vec { gen!(FaultyTrafficLightResp, _,"../dumped_data/faulty_traffic_lights.json") } pub fn passenger_vol_bus_stops() -> Vec { gen!(PassengerVolRawResp,_,"../dumped_data/passenger_vol_bus_stops.json") } pub fn passenger_vol_od_bus_stops() -> Vec { gen!(PassengerVolRawResp,_,"../dumped_data/passenger_vol_od_bus_stops.json") } pub fn passenger_vol_od_train() -> Vec { gen!(PassengerVolRawResp,_,"../dumped_data/passenger_vol_od_train.json") } pub fn passenger_vol_train() -> Vec { gen!(PassengerVolRawResp,_,"../dumped_data/passenger_vol_train.json") } pub fn taxi_avail() -> Vec { gen!(TaxiAvailResp, _, "../dumped_data/taxi_avail.json") } pub fn taxi_stands() -> Vec { gen!(TaxiStandsResp, _, "../dumped_data/taxi_stands.json") } pub fn train_service_alert() -> TrainServiceAlert { gen!(TrainServiceAlertResp,_,"../dumped_data/train_service_alert.json") } pub fn est_travel_time() -> Vec { gen!(EstTravelTimeResp, _, "../dumped_data/est_travel_time.json") } pub fn crowd_density_rt() -> Vec { gen!(StationCrowdLevelRawResp, _, "../dumped_data/crowd_density_rt.json") } pub fn crowd_density_forecast() -> CrowdDensityForecast { gen!(CrowdDensityForecastRawResp, _, "../dumped_data/crowd_density_forecast.json") } pub fn transmute_nextbus(data: NextBusRaw) -> NextBus { let nx = unsafe { std::mem::transmute::<_, NextBus>(data) }; nx } } #[rustfmt::skip] pub fn criterion_benchmark(c: &mut Criterion) { let sample_data = NextBusRaw { origin_code: 77009, dest_code: 77009, est_arrival: datetime!(2023-04-06 14:47:57 +8), lat: 1.314452, long: 103.910009, visit_no: 1, load: BusLoad::SeatsAvailable, feature: BusFeature::WheelChairAccessible, bus_type: BusType::SingleDecker, }; c.bench_function("transmute_nextbus", |b| b.iter(|| de::transmute_nextbus(black_box(sample_data.clone())))); c.bench_function("into_nextbus", |b| b.iter(|| NextBus::from(black_box(sample_data.clone())))); c.bench_function("de::bike_parking.json", |b| b.iter(|| de::bike_parking())); c.bench_function("de::bus_arrival.json", |b| b.iter(|| de::bus_arrival())); c.bench_function("de::bus_route.json", |b| b.iter(|| de::bus_routes())); c.bench_function("de::bus_services.json", |b| b.iter(|| de::bus_service())); c.bench_function("de::bus_stops.json", |b| b.iter(|| de::bus_stops())); c.bench_function("de::carpark_avail.json", |b| b.iter(|| de::carpark_avail())); c.bench_function("de::erp_rates.json", |b| b.iter(|| de::erp_rates())); c.bench_function("de::est_travel_time.json", |b| b.iter(|| de::est_travel_time())); c.bench_function("de::faulty_traffic_lights.json", |b| b.iter(|| de::faulty_traffic_lights())); c.bench_function("de::passenger_vol_bus_stops.json", |b| b.iter(|| de::passenger_vol_bus_stops())); c.bench_function("de::passenger_od_bus_stops.json", |b| b.iter(|| de::passenger_vol_od_bus_stops())); c.bench_function("de::passenger_vol_od_train.json", |b| b.iter(|| de::passenger_vol_od_train())); c.bench_function("de::passenger_vol_train.json", |b| b.iter(|| de::passenger_vol_train())); c.bench_function("de::taxi_avail.json", |b| b.iter(|| de::taxi_avail())); c.bench_function("de::taxi_stands.json", |b| b.iter(|| de::taxi_stands())); c.bench_function("de::train_service_alert.json", |b| b.iter(|| de::train_service_alert())); c.bench_function("de::crowd_density_rt.json", |b| b.iter(|| de::crowd_density_rt())); c.bench_function("de::crowd_density_forecast.json", |b| b.iter(|| de::crowd_density_forecast())); let bike_parking = de::bike_parking(); let bus_arrival = de::bus_arrival(); let bus_routes = de::bus_routes(); let bus_service = de::bus_service(); let bus_stops = de::bus_stops(); let carpark_avail = de::carpark_avail(); let erp_rates = de::erp_rates(); let est_travel_time = de::est_travel_time(); let faulty_traffic_lights = de::faulty_traffic_lights(); let passenger_vol_bus_stops = de::passenger_vol_bus_stops(); let passenger_vol_od_bus_stops = de::passenger_vol_od_bus_stops(); let passenger_vol_train = de::passenger_vol_train(); let passenger_vol_od_train = de::passenger_vol_od_train(); let taxi_avail = de::taxi_avail(); let taxi_stands = de::taxi_stands(); let train_service_alert = de::train_service_alert(); let crowd_density_rt = de::crowd_density_rt(); let crowd_density_forecast = de::crowd_density_forecast(); c.bench_function("ser::bike_parking.json", |b| b.iter(|| serde_json::to_string(black_box(&bike_parking)))); c.bench_function("ser::bus_arrival.json", |b| b.iter(|| serde_json::to_string(black_box(&bus_arrival)))); c.bench_function("ser::bus_route.json", |b| b.iter(|| serde_json::to_string(black_box(&bus_routes)))); c.bench_function("ser::bus_services.json", |b| b.iter(|| serde_json::to_string(black_box(&bus_service)))); c.bench_function("ser::bus_stops.json", |b| b.iter(|| serde_json::to_string(black_box(&bus_stops)))); c.bench_function("ser::carpark_avail.json", |b| b.iter(|| serde_json::to_string(black_box(&carpark_avail)))); c.bench_function("ser::erp_rates.json", |b| b.iter(|| serde_json::to_string(black_box(&erp_rates)))); c.bench_function("ser::est_travel_time.json", |b| b.iter(|| serde_json::to_string(black_box(&est_travel_time)))); c.bench_function("ser::faulty_traffic_lights.json", |b| b.iter(|| serde_json::to_string(black_box(&faulty_traffic_lights)))); c.bench_function("ser::passenger_vol_bus_stops.json", |b| b.iter(|| serde_json::to_string(black_box(&passenger_vol_bus_stops)))); c.bench_function("ser::passenger_od_bus_stops.json", |b| b.iter(|| serde_json::to_string(black_box(&passenger_vol_od_bus_stops)))); c.bench_function("ser::passenger_vol_od_train.json", |b| b.iter(|| serde_json::to_string(black_box(&passenger_vol_od_train)))); c.bench_function("ser::passenger_vol_train.json", |b| b.iter(|| serde_json::to_string(black_box(&passenger_vol_train)))); c.bench_function("ser::taxi_avail.json", |b| b.iter(|| serde_json::to_string(black_box(&taxi_avail)))); c.bench_function("ser::taxi_stands.json", |b| b.iter(|| serde_json::to_string(black_box(&taxi_stands)))); c.bench_function("ser::train_service_alert.json", |b| b.iter(|| serde_json::to_string(black_box(&train_service_alert)))); c.bench_function("ser::crowd_density_rt.json", |b| b.iter(|| serde_json::to_string(black_box(&crowd_density_rt)))); c.bench_function("ser::crowd_density_forecast.json", |b| b.iter(|| serde_json::to_string(black_box(&crowd_density_forecast)))); } criterion_group!(benches, criterion_benchmark); criterion_main!(benches);