// All benchmarks are exported as C functions so that they can be called from // the C++. The benchmarks are exported with the name of the benchmark // followed by the name of the kernel and _bench. use bench_data_rust_proto::BenchData; use paste::paste; use std::sync::OnceLock; macro_rules! export_proto_bench { ($name:ident, $protokernel:ident) => { paste! { #[no_mangle] pub extern "C" fn [<$name _rs_ $protokernel _bench>] () { $name(); } } }; } macro_rules! export_benches { ($name:ident, $($rest:tt)*) => { #[cfg(bench_upb)] export_proto_bench!($name, upb); #[cfg(bench_cpp)] export_proto_bench!($name, cpp); export_benches!($($rest)*); }; ($name:ident) => { #[cfg(bench_upb)] export_proto_bench!($name, upb); #[cfg(bench_cpp)] export_proto_bench!($name, cpp); }; } export_benches!( set_string, set_int, add_10_repeated_msg, copy_from_10_repeated_msg, extend_10_repeated_msg, add_100_ints, copy_from_100_ints, extend_100_ints, sum_1000_ints ); pub fn set_string() { let mut data = BenchData::new(); data.set_name("a relatively long string that will avoid any short string optimizations."); } pub fn set_int() { let mut data = BenchData::new(); data.set_num2(123456789); assert_eq!(data.num2(), 123456789); } pub fn add_10_repeated_msg() { let mut data = BenchData::new(); let mut repeated = data.subs_mut(); for i in 0..10 { let mut new = BenchData::new(); new.set_num2(i); repeated.push(new.as_view()); } } static COPY_FROM_10: OnceLock = OnceLock::new(); fn create_10_repeated() -> BenchData { let mut data = BenchData::new(); let mut repeated = data.subs_mut(); for i in 0..10 { let mut new = BenchData::new(); new.set_num2(i); repeated.push(new.as_view()); } data } pub fn copy_from_10_repeated_msg() { let source = COPY_FROM_10.get_or_init(create_10_repeated); let mut data = BenchData::new(); data.subs_mut().copy_from(source.subs()); } pub fn extend_10_repeated_msg() { let source = COPY_FROM_10.get_or_init(create_10_repeated); let mut data = BenchData::new(); data.subs_mut().extend(source.subs()); } pub fn add_100_ints() { let mut data = BenchData::new(); let mut repeated = data.nums_mut(); for i in 0..100 { repeated.push(i); } } fn create_100_ints() -> BenchData { let mut data = BenchData::new(); data.nums_mut().extend(0..100); data } static COPY_FROM_100: OnceLock = OnceLock::new(); pub fn copy_from_100_ints() { let source = COPY_FROM_100.get_or_init(create_100_ints); let mut data = BenchData::new(); data.nums_mut().copy_from(source.nums()); } pub fn extend_100_ints() { let mut data = BenchData::new(); let mut repeated = data.nums_mut(); repeated.extend(0..100); assert!(repeated.len() == 100); } static ONE_THOUSAND: OnceLock = OnceLock::new(); pub fn sum_1000_ints() { let source = ONE_THOUSAND.get_or_init(|| { let mut data = BenchData::new(); data.nums_mut().extend(0..1000); data }); let sum: i32 = source.nums().iter().sum(); assert!(sum == 499500); }