From 54f210bdddd7da65598417616f67472ac9958fc0 Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 27 Mar 2025 17:16:53 +0000 Subject: [PATCH 1/4] feat: improve tracing spans, add `profile_with_tracy` feature flag --- Cargo.toml | 1 + benches/benchmarks.rs | 163 +++++++++++++++++- crates/bevy_mod_scripting_core/Cargo.toml | 2 +- crates/bevy_mod_scripting_core/src/asset.rs | 8 + .../src/bindings/function/from.rs | 23 ++- .../src/bindings/function/into.rs | 34 ++-- .../src/bindings/function/into_ref.rs | 2 + .../src/bindings/function/namespace.rs | 2 + .../src/bindings/function/script_function.rs | 44 +++-- .../src/bindings/globals/core.rs | 3 + .../src/bindings/globals/mod.rs | 2 + .../src/bindings/query.rs | 5 + .../src/bindings/schedule.rs | 1 + .../src/bindings/script_component.rs | 3 + .../src/bindings/script_system.rs | 6 + .../src/bindings/script_value.rs | 13 ++ .../src/bindings/world.rs | 6 + .../bevy_mod_scripting_core/src/commands.rs | 3 + .../src/docgen/info.rs | 4 + crates/bevy_mod_scripting_core/src/lib.rs | 1 + crates/bevy_mod_scripting_core/src/runtime.rs | 1 + crates/bevy_mod_scripting_core/src/script.rs | 2 + .../src/lib.rs | 60 ++++++- .../src/test_functions.rs | 4 +- crates/testing_crates/test_utils/src/lib.rs | 14 +- 25 files changed, 356 insertions(+), 51 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70738d6ee6..14e902b0eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,6 +89,7 @@ script_integration_test_harness = { workspace = true } test_utils = { workspace = true } libtest-mimic = "0.8" tracing-tracy = "0.11" +regex = "1.11" [workspace] members = [ diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index cd7f4f6e24..d4b96f391f 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -1,8 +1,19 @@ -use bevy::log::tracing_subscriber; use bevy::log::tracing_subscriber::layer::SubscriberExt; -use bevy::utils::{tracing, HashMap}; +use bevy::log::{tracing_subscriber, Level}; +use bevy::reflect::Reflect; +use bevy::utils::tracing; +use bevy::utils::tracing::span; +use bevy_mod_scripting_core::bindings::{ + FromScript, IntoScript, Mut, Ref, ReflectReference, ScriptValue, Val, +}; use criterion::{criterion_main, measurement::Measurement, BenchmarkGroup, Criterion}; -use script_integration_test_harness::{run_lua_benchmark, run_rhai_benchmark}; +use criterion::{BatchSize, BenchmarkFilter}; +use regex::Regex; +use script_integration_test_harness::test_functions::rand::Rng; +use script_integration_test_harness::{ + perform_benchmark_with_generator, run_lua_benchmark, run_rhai_benchmark, +}; +use std::collections::HashMap; use std::{path::PathBuf, sync::LazyLock, time::Duration}; use test_utils::{discover_all_tests, Test}; @@ -65,10 +76,24 @@ impl BenchmarkExecutor for Test { } } -fn script_benchmarks(criterion: &mut Criterion) { +fn script_benchmarks(criterion: &mut Criterion, filter: Option) { // find manifest dir let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let tests = discover_all_tests(manifest_dir, |p| p.starts_with("benchmarks")); + let tests = discover_all_tests(manifest_dir, |p| { + p.path.starts_with("benchmarks") + && if let Some(filter) = &filter { + let matching = filter.is_match(&p.benchmark_name()); + if !matching { + println!( + "Skipping benchmark: '{}'. due to filter: '{filter}'", + p.benchmark_name() + ); + }; + matching + } else { + true + } + }); // group by benchmark group let mut grouped: HashMap> = @@ -83,9 +108,16 @@ fn script_benchmarks(criterion: &mut Criterion) { } for (group, tests) in grouped { + println!("Running benchmarks for group: {}", group); let mut benchmark_group = criterion.benchmark_group(group); for t in tests { + println!("Running benchmark: {}", t.benchmark_name()); + span!( + Level::INFO, + "Benchmark harness for test", + test_name = &t.benchmark_name() + ); t.execute(&mut benchmark_group); } @@ -104,22 +136,135 @@ fn maybe_with_profiler(f: impl Fn(bool)) { tracing::subscriber::set_global_default(subscriber).unwrap(); - let _ = tracing_tracy::client::span!("test2"); - tracing::info_span!("test"); - f(true); } else { f(false); } } +/// benchmarks measuring conversion time for script values and other things +fn conversion_benchmarks(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group("conversions"); + + #[derive(Reflect)] + struct ReflectyVal(pub u32); + + perform_benchmark_with_generator( + "ScriptValue::List", + &|rng, _| { + let mut array = Vec::new(); + for _ in 0..10 { + array.push(ScriptValue::Integer(rng.random())); + } + ScriptValue::List(array) + }, + &|w, i| { + let i = i.into_script(w.clone()).unwrap(); + let _ = Vec::::from_script(i, w).unwrap(); + }, + &mut group, + BatchSize::SmallInput, + ); + + perform_benchmark_with_generator( + "ScriptValue::Map", + &|rng, _| { + let mut map = HashMap::default(); + for _ in 0..10 { + map.insert( + rng.random::().to_string(), + ScriptValue::Integer(rng.random()), + ); + } + ScriptValue::Map(map) + }, + &|w, i| { + let i = i.into_script(w.clone()).unwrap(); + let _ = HashMap::::from_script(i, w).unwrap(); + }, + &mut group, + BatchSize::SmallInput, + ); + + perform_benchmark_with_generator( + "ScriptValue::Reference::from_into", + &|rng, world| { + let allocator = world.allocator(); + let mut allocator = allocator.write(); + ReflectReference::new_allocated(ReflectyVal(rng.random()), &mut allocator) + }, + &|w, i| { + let i = i.into_script(w.clone()).unwrap(); + let _ = ReflectReference::from_script(i, w).unwrap(); + }, + &mut group, + BatchSize::SmallInput, + ); + + perform_benchmark_with_generator( + "Val::from_into", + &|rng, _| Val::new(ReflectyVal(rng.random::())), + &|w, i| { + let v = i.into_script(w.clone()).unwrap(); + Val::::from_script(v, w).unwrap(); + }, + &mut group, + BatchSize::SmallInput, + ); + + perform_benchmark_with_generator( + "Ref::from", + &|rng, w| { + Val::new(ReflectyVal(rng.random::())) + .into_script(w) + .unwrap() + }, + &|w, i| { + Ref::::from_script(i, w).unwrap(); + }, + &mut group, + BatchSize::SmallInput, + ); + + perform_benchmark_with_generator( + "Mut::from", + &|rng, w| { + Val::new(ReflectyVal(rng.random::())) + .into_script(w) + .unwrap() + }, + &|w, i| { + Mut::::from_script(i, w).unwrap(); + }, + &mut group, + BatchSize::SmallInput, + ); +} + pub fn benches() { maybe_with_profiler(|_profiler| { let mut criterion: criterion::Criterion<_> = (criterion::Criterion::default()) .configure_from_args() .measurement_time(Duration::from_secs(10)); + let arguments = std::env::args() + .skip(1) // the executable name + .filter(|a| !a.starts_with("-")) + .collect::>(); + + // take first argument as .*.* regex for benchmarks + // criterion will already have that as a filter, but we want to make sure we're on the same page + let filter = if let Some(n) = arguments.first() { + println!("using filter: '{n}'"); + let regex = Regex::new(n).unwrap(); + let filter = BenchmarkFilter::Regex(regex.clone()); + criterion = criterion.with_benchmark_filter(filter); + Some(regex) + } else { + None + }; - script_benchmarks(&mut criterion); + script_benchmarks(&mut criterion, filter); + conversion_benchmarks(&mut criterion); }); } criterion_main!(benches); diff --git a/crates/bevy_mod_scripting_core/Cargo.toml b/crates/bevy_mod_scripting_core/Cargo.toml index ed0690e6b8..c2b0340d18 100644 --- a/crates/bevy_mod_scripting_core/Cargo.toml +++ b/crates/bevy_mod_scripting_core/Cargo.toml @@ -33,7 +33,7 @@ bevy = { workspace = true, default-features = false, features = ["bevy_asset"] } thiserror = "1.0.31" parking_lot = "0.12.1" dashmap = "6" -smallvec = "1.11" +smallvec = { version = "1.11", features = ["union"] } itertools = "0.13" derivative = "2.2" profiling = { workspace = true } diff --git a/crates/bevy_mod_scripting_core/src/asset.rs b/crates/bevy_mod_scripting_core/src/asset.rs index 8891a9264b..5b122ab7f8 100644 --- a/crates/bevy_mod_scripting_core/src/asset.rs +++ b/crates/bevy_mod_scripting_core/src/asset.rs @@ -73,6 +73,7 @@ pub struct ScriptAssetLoader { pub preprocessor: Option Result<(), ScriptError> + Send + Sync>>, } +#[profiling::all_functions] impl AssetLoader for ScriptAssetLoader { type Asset = ScriptAsset; @@ -121,6 +122,7 @@ pub struct ScriptAssetSettings { pub supported_extensions: &'static [&'static str], } +#[profiling::all_functions] impl ScriptAssetSettings { /// Selects the language for a given asset path pub fn select_script_language(&self, path: &AssetPath) -> Language { @@ -178,6 +180,7 @@ pub struct ScriptMetadata { pub language: Language, } +#[profiling::all_functions] impl ScriptMetadataStore { /// Inserts a new metadata entry pub fn insert(&mut self, id: AssetId, meta: ScriptMetadata) { @@ -202,6 +205,7 @@ impl ScriptMetadataStore { } /// Converts incoming asset events, into internal script asset events, also loads and inserts metadata for newly added scripts +#[profiling::function] pub(crate) fn dispatch_script_asset_events( mut events: EventReader>, mut script_asset_events: EventWriter, @@ -256,6 +260,7 @@ pub(crate) fn dispatch_script_asset_events( } /// Listens to [`ScriptAssetEvent::Removed`] events and removes the corresponding script metadata. +#[profiling::function] pub(crate) fn remove_script_metadata( mut events: EventReader, mut asset_path_map: ResMut, @@ -273,6 +278,7 @@ pub(crate) fn remove_script_metadata( /// Listens to [`ScriptAssetEvent`] events and dispatches [`CreateOrUpdateScript`] and [`DeleteScript`] commands accordingly. /// /// Allows for hot-reloading of scripts. +#[profiling::function] pub(crate) fn sync_script_data( mut events: EventReader, script_assets: Res>, @@ -321,6 +327,7 @@ pub(crate) fn sync_script_data( } /// Setup all the asset systems for the scripting plugin and the dependencies +#[profiling::function] pub(crate) fn configure_asset_systems(app: &mut App) -> &mut App { // these should be in the same set as bevy's asset systems // currently this is in the PreUpdate set @@ -348,6 +355,7 @@ pub(crate) fn configure_asset_systems(app: &mut App) -> &mut App { } /// Setup all the asset systems for the scripting plugin and the dependencies +#[profiling::function] pub(crate) fn configure_asset_systems_for_plugin( app: &mut App, ) -> &mut App { diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs index 98c9422020..0852840708 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/from.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/from.rs @@ -32,6 +32,7 @@ pub trait FromScript { Self: Sized; } +#[profiling::all_functions] impl FromScript for ScriptValue { type This<'w> = Self; fn from_script(value: ScriptValue, _world: WorldGuard) -> Result { @@ -39,6 +40,7 @@ impl FromScript for ScriptValue { } } +#[profiling::all_functions] impl FromScript for () { type This<'w> = Self; fn from_script(_value: ScriptValue, _world: WorldGuard) -> Result { @@ -46,6 +48,7 @@ impl FromScript for () { } } +#[profiling::all_functions] impl FromScript for bool { type This<'w> = Self; #[profiling::function] @@ -70,6 +73,7 @@ impl FromScript for bool { macro_rules! impl_from_with_downcast { ($($ty:ty),*) => { $( + #[profiling::all_functions] impl FromScript for $ty { type This<'w> = Self; #[profiling::function] @@ -92,6 +96,7 @@ impl_from_with_downcast!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, macro_rules! impl_from_stringlike { ($($ty:ty),*) => { $( + #[profiling::all_functions] impl FromScript for $ty { type This<'w> = Self; #[profiling::function] @@ -109,6 +114,7 @@ macro_rules! impl_from_stringlike { impl_from_stringlike!(String, PathBuf, OsString); +#[profiling::all_functions] impl FromScript for char { type This<'w> = Self; #[profiling::function] @@ -133,6 +139,7 @@ impl FromScript for char { } } +#[profiling::all_functions] impl FromScript for ReflectReference { type This<'w> = Self; #[profiling::function] @@ -154,6 +161,7 @@ impl FromScript for ReflectReference { #[derive(Reflect)] pub struct Val(pub T); +#[profiling::all_functions] impl Val { /// Create a new `Val` with the given value. pub fn new(value: T) -> Self { @@ -186,6 +194,7 @@ impl From for Val { } } +#[profiling::all_functions] impl FromScript for Val { type This<'w> = Self; #[profiling::function] @@ -230,6 +239,7 @@ impl Deref for Ref<'_, T> { } } +#[profiling::all_functions] impl FromScript for Ref<'_, T> { type This<'a> = Ref<'a, T>; #[profiling::function] @@ -302,6 +312,7 @@ impl<'a, T> From<&'a mut T> for Mut<'a, T> { } } +#[profiling::all_functions] impl FromScript for Mut<'_, T> { type This<'w> = Mut<'w, T>; #[profiling::function] @@ -337,6 +348,7 @@ impl FromScript for Mut<'_, T> { } } +#[profiling::all_functions] impl FromScript for Option where for<'w> T::This<'w>: Into, @@ -351,6 +363,7 @@ where } } +#[profiling::all_functions] impl FromScript for Vec where for<'w> T::This<'w>: Into, @@ -374,6 +387,7 @@ where } } +#[profiling::all_functions] impl FromScript for [T; N] where for<'w> T::This<'w>: Into, @@ -399,6 +413,7 @@ where } } +#[profiling::all_functions] impl FromScript for DynamicScriptFunctionMut { type This<'w> = Self; #[profiling::function] @@ -416,6 +431,7 @@ impl FromScript for DynamicScriptFunctionMut { } } +#[profiling::all_functions] impl FromScript for DynamicScriptFunction { type This<'w> = Self; #[profiling::function] @@ -433,6 +449,7 @@ impl FromScript for DynamicScriptFunction { } } +#[profiling::all_functions] impl FromScript for std::collections::HashMap where V: FromScript + 'static, @@ -468,6 +485,7 @@ where /// A union of two or more (by nesting unions) types. pub struct Union(Result); +#[profiling::all_functions] impl Union { /// Create a new union with the left value. pub fn new_left(value: T1) -> Self { @@ -479,7 +497,6 @@ impl Union { Union(Err(value)) } - /// Try interpret the union as the left type pub fn into_left(self) -> Result { match self.0 { @@ -495,7 +512,7 @@ impl Union { Ok(l) => Err(l), } } - + /// Map the union to another type pub fn map_both U1, G: Fn(T2) -> U2>(self, f: F, g: G) -> Union { match self.0 { @@ -505,6 +522,7 @@ impl Union { } } +#[profiling::all_functions] impl FromScript for Union where for<'a> T1::This<'a>: Into, @@ -530,6 +548,7 @@ where macro_rules! impl_from_script_tuple { ($($ty:ident),*) => { #[allow(non_snake_case)] + #[profiling::all_functions] impl<$($ty: FromScript),*> FromScript for ($($ty,)*) where Self: 'static, diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/into.rs b/crates/bevy_mod_scripting_core/src/bindings/function/into.rs index a841ad714c..fd1fb88e9b 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/into.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/into.rs @@ -1,10 +1,13 @@ //! Implementations of the [`IntoScript`] trait for various types. -use std::{borrow::Cow, collections::HashMap, ffi::OsString, path::PathBuf}; use bevy::reflect::Reflect; +use std::{borrow::Cow, collections::HashMap, ffi::OsString, path::PathBuf}; -use crate::{bindings::{ReflectReference, ScriptValue, WorldGuard}, error::InteropError}; use super::{DynamicScriptFunction, DynamicScriptFunctionMut, Union, Val}; +use crate::{ + bindings::{ReflectReference, ScriptValue, WorldGuard}, + error::InteropError, +}; /// Converts a value into a [`ScriptValue`]. pub trait IntoScript { @@ -26,27 +29,28 @@ impl IntoScript for ScriptValue { } } - +#[profiling::all_functions] impl IntoScript for () { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::Unit) } } - +#[profiling::all_functions] impl IntoScript for DynamicScriptFunctionMut { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::FunctionMut(self)) } } +#[profiling::all_functions] impl IntoScript for DynamicScriptFunction { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::Function(self)) } } - +#[profiling::all_functions] impl IntoScript for bool { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::Bool(self)) @@ -56,6 +60,7 @@ impl IntoScript for bool { macro_rules! impl_into_with_downcast { ($variant:tt as $cast:ty [$($ty:ty),*]) => { $( + #[profiling::all_functions] impl IntoScript for $ty { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::$variant(self as $cast)) @@ -69,10 +74,10 @@ macro_rules! impl_into_with_downcast { impl_into_with_downcast!(Integer as i64 [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize]); impl_into_with_downcast!(Float as f64 [f32, f64]); - macro_rules! impl_into_stringlike { ($id:ident,[ $(($ty:ty => $conversion:expr)),*]) => { $( + #[profiling::all_functions] impl IntoScript for $ty { fn into_script(self, _world: WorldGuard) -> Result { let $id = self; @@ -94,21 +99,21 @@ impl_into_stringlike!( ] ); - +#[profiling::all_functions] impl IntoScript for &'static str { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::String(Cow::Borrowed(self))) } } - - +#[profiling::all_functions] impl IntoScript for ReflectReference { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::Reference(self)) } } +#[profiling::all_functions] impl IntoScript for Val { fn into_script(self, world: WorldGuard) -> Result { let boxed = Box::new(self.0); @@ -121,6 +126,7 @@ impl IntoScript for Val { } } +#[profiling::all_functions] impl IntoScript for Option { fn into_script(self, world: WorldGuard) -> Result { match self { @@ -130,6 +136,7 @@ impl IntoScript for Option { } } +#[profiling::all_functions] impl IntoScript for Vec { fn into_script(self, world: WorldGuard) -> Result { let mut values = Vec::with_capacity(self.len()); @@ -140,6 +147,7 @@ impl IntoScript for Vec { } } +#[profiling::all_functions] impl IntoScript for [T; N] { fn into_script(self, world: WorldGuard) -> Result { let mut values = Vec::with_capacity(N); @@ -150,15 +158,17 @@ impl IntoScript for [T; N] { } } -impl IntoScript for Union { +#[profiling::all_functions] +impl IntoScript for Union { fn into_script(self, world: WorldGuard) -> Result { match self.into_left() { Ok(left) => left.into_script(world), Err(right) => right.into_script(world), } } -} +} +#[profiling::all_functions] impl IntoScript for HashMap { fn into_script(self, world: WorldGuard) -> Result { let mut map = HashMap::new(); @@ -169,6 +179,7 @@ impl IntoScript for HashMap { } } +#[profiling::all_functions] impl IntoScript for InteropError { fn into_script(self, _world: WorldGuard) -> Result { Ok(ScriptValue::Error(self)) @@ -178,6 +189,7 @@ impl IntoScript for InteropError { macro_rules! impl_into_script_tuple { ($( $ty:ident ),* ) => { #[allow(non_snake_case)] + #[profiling::all_functions] impl<$($ty: IntoScript),*> IntoScript for ($($ty,)*) { fn into_script(self, world: WorldGuard) -> Result { let ($($ty,)*) = self; diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs b/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs index bdce9f9630..ca29e7c8f5 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/into_ref.rs @@ -54,6 +54,7 @@ macro_rules! downcast_into_value { }; } +#[profiling::all_functions] impl IntoScriptRef for ReflectReference { #[profiling::function] fn into_script_ref( @@ -63,6 +64,7 @@ impl IntoScriptRef for ReflectReference { self_.with_reflect(world.clone(), |r| into_script_ref(self_.clone(), r, world))? } } + #[profiling::function] fn into_script_ref( mut self_: ReflectReference, diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs b/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs index e9f4d5b30f..390393abfb 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/namespace.rs @@ -44,6 +44,7 @@ impl IntoNamespace for T { } /// A type which implements [`IntoNamespace`] by always converting to the global namespace +#[profiling::all_functions] impl Namespace { /// Returns the prefix for this namespace pub fn prefix(self) -> Cow<'static, str> { @@ -70,6 +71,7 @@ pub struct NamespaceBuilder<'a, N> { pub world: &'a mut World, } +#[profiling::all_functions] impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> { /// Creates a new `NamespaceBuilder` that will register functions in the namespace corresponding to the given type /// It will also register the type itself in the type registry. diff --git a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs index 88200962e8..d0627f67a7 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs @@ -44,6 +44,7 @@ pub trait ScriptFunctionMut<'env, Marker> { pub struct FunctionCallContext { language: Language, } + impl FunctionCallContext { /// Create a new FunctionCallContext with the given 1-indexing conversion preference pub const fn new(language: Language) -> Self { @@ -51,15 +52,18 @@ impl FunctionCallContext { } /// Tries to access the world, returning an error if the world is not available + #[profiling::function] pub fn world<'l>(&self) -> Result, InteropError> { ThreadWorldContainer.try_get_world() } /// Whether the caller uses 1-indexing on all indexes and expects 0-indexing conversions to be performed. + #[profiling::function] pub fn convert_to_0_indexed(&self) -> bool { matches!(&self.language, Language::Lua) } /// Gets the scripting language of the caller + #[profiling::function] pub fn language(&self) -> Language { self.language.clone() } @@ -94,6 +98,7 @@ pub struct DynamicScriptFunctionMut { >, } +#[profiling::all_functions] impl DynamicScriptFunction { /// Call the function with the given arguments and caller context. /// @@ -150,6 +155,7 @@ impl DynamicScriptFunction { } } +#[profiling::all_functions] impl DynamicScriptFunctionMut { /// Call the function with the given arguments and caller context. /// @@ -283,6 +289,7 @@ impl DerefMut for AppScriptFunctionRegistry { /// A thread-safe reference counted wrapper around a [`ScriptFunctionRegistry`] pub struct ScriptFunctionRegistryArc(pub Arc>); +#[profiling::all_functions] impl ScriptFunctionRegistryArc { /// claim a read lock on the registry pub fn read(&self) -> RwLockReadGuard { @@ -593,6 +600,7 @@ macro_rules! impl_script_function { let func = (move |caller_context: FunctionCallContext, mut args: VecDeque | { let res: Result = (|| { + profiling::scope!("script function call mechanism"); let received_args_len = args.len(); let expected_arg_count = count!($($param )*); @@ -603,29 +611,37 @@ macro_rules! impl_script_function { world.with_access_scope(||{ let mut current_arg = 0; - $( - current_arg += 1; - let $param = args.pop_front(); - let $param = match $param { - Some($param) => $param, - None => { - if let Some(default) = <$param>::default_value() { - default - } else { - return Err(InteropError::argument_count_mismatch(expected_arg_count,received_args_len)); + $(let $param = { + profiling::scope!("argument conversion", &format!("argument #{}", current_arg)); + current_arg += 1; + let $param = args.pop_front(); + let $param = match $param { + Some($param) => $param, + None => { + if let Some(default) = <$param>::default_value() { + default + } else { + return Err(InteropError::argument_count_mismatch(expected_arg_count,received_args_len)); + } } - } + }; + let $param = <$param>::from_script($param, world.clone()) + .map_err(|e| InteropError::function_arg_conversion_error(current_arg.to_string(), e))?; + $param }; - let $param = <$param>::from_script($param, world.clone()) - .map_err(|e| InteropError::function_arg_conversion_error(current_arg.to_string(), e))?; )* let ret = { - let out = self( $( $context,)? $( $param.into(), )* ); + let out = { + profiling::scope!("function call"); + self( $( $context,)? $( $param.into(), )* ) + }; + $( let $out = out?; let out = $out; )? + profiling::scope!("return type conversion"); out.into_script(world.clone()).map_err(|e| InteropError::function_arg_conversion_error("return value".to_owned(), e)) }; ret diff --git a/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs b/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs index 394fe4d6b3..9960205917 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/globals/core.rs @@ -26,11 +26,13 @@ pub struct CoreScriptGlobalsPlugin; impl Plugin for CoreScriptGlobalsPlugin { fn build(&self, _app: &mut bevy::app::App) {} fn finish(&self, app: &mut bevy::app::App) { + profiling::function_scope!("app finish"); register_static_core_globals(app.world_mut()); register_core_globals(app.world_mut()); } } +#[profiling::function] fn register_static_core_globals(world: &mut bevy::ecs::world::World) { let global_registry = world .get_resource_or_init::() @@ -83,6 +85,7 @@ impl CoreGlobals { >, InteropError, > { + profiling::function_scope!("registering core globals"); let type_registry = guard.type_registry(); let type_registry = type_registry.read(); let mut type_cache = HashMap::::default(); diff --git a/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs b/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs index a1f9d7d6ab..42f4d2de80 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/globals/mod.rs @@ -21,6 +21,7 @@ crate::private::export_all_in_modules! { #[derive(Default, Resource, Clone)] pub struct AppScriptGlobalsRegistry(Arc>); +#[profiling::all_functions] impl AppScriptGlobalsRegistry { /// Returns a reference to the inner [`ScriptGlobalsRegistry`]. pub fn read(&self) -> RwLockReadGuard { @@ -69,6 +70,7 @@ pub struct ScriptGlobalsRegistry { dummies: HashMap, ScriptGlobalDummy>, } +#[profiling::all_functions] impl ScriptGlobalsRegistry { /// Gets the global with the given name pub fn get(&self, name: &str) -> Option<&ScriptGlobal> { diff --git a/crates/bevy_mod_scripting_core/src/bindings/query.rs b/crates/bevy_mod_scripting_core/src/bindings/query.rs index 33e4ce3c02..b13fe9f63a 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/query.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/query.rs @@ -47,6 +47,7 @@ pub struct ScriptResourceRegistration { pub(crate) resource_id: ComponentId, } +#[profiling::all_functions] impl ScriptTypeRegistration { /// Creates a new [`ScriptTypeRegistration`] from a [`TypeRegistration`]. pub fn new(registration: Arc) -> Self { @@ -76,6 +77,8 @@ impl ScriptTypeRegistration { &self.registration } } + +#[profiling::all_functions] impl ScriptResourceRegistration { /// Creates a new [`ScriptResourceRegistration`] from a [`ScriptTypeRegistration`] and a [`ComponentId`]. pub fn new(registration: ScriptTypeRegistration, resource_id: ComponentId) -> Self { @@ -102,6 +105,7 @@ impl ScriptResourceRegistration { } } +#[profiling::all_functions] impl ScriptComponentRegistration { /// Creates a new [`ScriptComponentRegistration`] from a [`ScriptTypeRegistration`] and a [`ComponentId`]. pub fn new(registration: ScriptTypeRegistration, component_id: ComponentId) -> Self { @@ -250,6 +254,7 @@ pub struct ScriptQueryBuilder { without: Vec, } +#[profiling::all_functions] impl ScriptQueryBuilder { /// Adds components to the query. pub fn components(&mut self, components: Vec) -> &mut Self { diff --git a/crates/bevy_mod_scripting_core/src/bindings/schedule.rs b/crates/bevy_mod_scripting_core/src/bindings/schedule.rs index 62bc2b7633..4e04dbdc78 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/schedule.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/schedule.rs @@ -44,6 +44,7 @@ pub struct ScheduleRegistry { schedules: HashMap, } +#[profiling::all_functions] impl ScheduleRegistry { /// Creates a new schedule registry containing all default bevy schedules. pub fn new() -> Self { diff --git a/crates/bevy_mod_scripting_core/src/bindings/script_component.rs b/crates/bevy_mod_scripting_core/src/bindings/script_component.rs index b1e12f3dc3..74243b29a3 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/script_component.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/script_component.rs @@ -37,6 +37,7 @@ impl Component for DynamicComponent { #[derive(Clone, Resource, Default)] pub struct AppScriptComponentRegistry(pub Arc>); +#[profiling::all_functions] impl AppScriptComponentRegistry { /// Reads the underlying registry pub fn read(&self) -> parking_lot::RwLockReadGuard { @@ -55,6 +56,7 @@ pub struct ScriptComponentRegistry { components: HashMap, } +#[profiling::all_functions] impl ScriptComponentRegistry { /// Registers a dynamic script component, possibly overwriting an existing one pub fn register(&mut self, info: DynamicComponentInfo) { @@ -67,6 +69,7 @@ impl ScriptComponentRegistry { } } +#[profiling::all_functions] impl WorldAccessGuard<'_> { /// Registers a dynamic script component, and returns a reference to its registration pub fn register_script_component( diff --git a/crates/bevy_mod_scripting_core/src/bindings/script_system.rs b/crates/bevy_mod_scripting_core/src/bindings/script_system.rs index f9be183de8..76d68370c8 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/script_system.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/script_system.rs @@ -49,6 +49,7 @@ impl std::fmt::Debug for ScriptSystemSet { } } +#[profiling::all_functions] impl ScriptSystemSet { /// Creates a new script system set pub fn new(id: impl Into>) -> Self { @@ -56,6 +57,7 @@ impl ScriptSystemSet { } } +#[profiling::all_functions] impl SystemSet for ScriptSystemSet { fn dyn_clone(&self) -> bevy::ecs::label::Box { Box::new(self.clone()) @@ -88,6 +90,7 @@ pub struct ScriptSystemBuilder { is_exclusive: bool, } +#[profiling::all_functions] impl ScriptSystemBuilder { /// Creates a new script system builder pub fn new(name: CallbackLabel, script_id: ScriptId) -> Self { @@ -197,6 +200,7 @@ struct DynamicHandlerContext<'w, P: IntoScriptPluginParams> { runtime_container: &'w RuntimeContainer

, } +#[profiling::all_functions] impl<'w, P: IntoScriptPluginParams> DynamicHandlerContext<'w, P> { #[allow( clippy::expect_used, @@ -345,6 +349,7 @@ pub struct DynamicScriptSystem { /// A marker type distinguishing between vanilla and script system types pub struct IsDynamicScriptSystem

(PhantomData P>); +#[profiling::all_functions] impl IntoSystem<(), (), IsDynamicScriptSystem

> for ScriptSystemBuilder { @@ -366,6 +371,7 @@ impl IntoSystem<(), (), IsDynamicScriptSystem

> } } +#[profiling::all_functions] impl System for DynamicScriptSystem

{ type In = (); diff --git a/crates/bevy_mod_scripting_core/src/bindings/script_value.rs b/crates/bevy_mod_scripting_core/src/bindings/script_value.rs index c8cbb21e48..7c15721940 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/script_value.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/script_value.rs @@ -41,6 +41,7 @@ pub enum ScriptValue { Error(InteropError), } +#[profiling::all_functions] impl ScriptValue { /// Returns the contained string if this is a string variant otherwise returns the original value. pub fn as_string(self) -> Result, Self> { @@ -68,66 +69,77 @@ impl ScriptValue { } } +#[profiling::all_functions] impl From<()> for ScriptValue { fn from(_: ()) -> Self { ScriptValue::Unit } } +#[profiling::all_functions] impl From for ScriptValue { fn from(value: bool) -> Self { ScriptValue::Bool(value) } } +#[profiling::all_functions] impl From for ScriptValue { fn from(value: i64) -> Self { ScriptValue::Integer(value) } } +#[profiling::all_functions] impl From for ScriptValue { fn from(value: f64) -> Self { ScriptValue::Float(value) } } +#[profiling::all_functions] impl From<&'static str> for ScriptValue { fn from(value: &'static str) -> Self { ScriptValue::String(value.into()) } } +#[profiling::all_functions] impl From for ScriptValue { fn from(value: String) -> Self { ScriptValue::String(value.into()) } } +#[profiling::all_functions] impl From> for ScriptValue { fn from(value: Cow<'static, str>) -> Self { ScriptValue::String(value) } } +#[profiling::all_functions] impl From> for ScriptValue { fn from(value: Vec) -> Self { ScriptValue::List(value) } } +#[profiling::all_functions] impl From for ScriptValue { fn from(value: ReflectReference) -> Self { ScriptValue::Reference(value) } } +#[profiling::all_functions] impl From for ScriptValue { fn from(value: InteropError) -> Self { ScriptValue::Error(value) } } +#[profiling::all_functions] impl> From> for ScriptValue { fn from(value: Option) -> Self { match value { @@ -137,6 +149,7 @@ impl> From> for ScriptValue { } } +#[profiling::all_functions] impl, E: Into> From> for ScriptValue { fn from(value: Result) -> Self { match value { diff --git a/crates/bevy_mod_scripting_core/src/bindings/world.rs b/crates/bevy_mod_scripting_core/src/bindings/world.rs index 79d082a6c1..2b2c749d51 100644 --- a/crates/bevy_mod_scripting_core/src/bindings/world.rs +++ b/crates/bevy_mod_scripting_core/src/bindings/world.rs @@ -93,6 +93,7 @@ impl std::fmt::Debug for WorldAccessGuardInner<'_> { } } +#[profiling::all_functions] impl WorldAccessGuard<'static> { /// Shortens the lifetime of the guard to the given lifetime. pub(crate) fn shorten_lifetime<'w>(self) -> WorldGuard<'w> { @@ -243,6 +244,11 @@ impl<'w> WorldAccessGuard<'w> { self.inner.accesses.list_accesses() } + /// Should only really be used for testing purposes + pub unsafe fn release_all_accesses(&self) { + self.inner.accesses.release_all_accesses(); + } + /// Returns the number of accesses currently held. pub fn access_len(&self) -> usize { self.inner.accesses.count_accesses() diff --git a/crates/bevy_mod_scripting_core/src/commands.rs b/crates/bevy_mod_scripting_core/src/commands.rs index 667661f8a8..02c49bb3a8 100644 --- a/crates/bevy_mod_scripting_core/src/commands.rs +++ b/crates/bevy_mod_scripting_core/src/commands.rs @@ -94,6 +94,7 @@ pub struct CreateOrUpdateScript { _ph: std::marker::PhantomData, } +#[profiling::all_functions] impl CreateOrUpdateScript

{ /// Creates a new CreateOrUpdateScript command with the given ID, content and asset pub fn new(id: ScriptId, content: Box<[u8]>, asset: Option>) -> Self { @@ -169,6 +170,7 @@ impl CreateOrUpdateScript

{ } } +#[profiling::all_functions] impl Command for CreateOrUpdateScript

{ fn apply(self, world: &mut bevy::prelude::World) { with_handler_system_state(world, |guard, handler_ctxt: &mut HandlerContext

| { @@ -293,6 +295,7 @@ impl RemoveStaticScript { } } +#[profiling::all_functions] impl Command for RemoveStaticScript { fn apply(self, world: &mut bevy::prelude::World) { let mut static_scripts = world.get_resource_or_init::(); diff --git a/crates/bevy_mod_scripting_core/src/docgen/info.rs b/crates/bevy_mod_scripting_core/src/docgen/info.rs index 46dcc7e1a9..1bb4c25fa1 100644 --- a/crates/bevy_mod_scripting_core/src/docgen/info.rs +++ b/crates/bevy_mod_scripting_core/src/docgen/info.rs @@ -34,6 +34,7 @@ impl Default for FunctionInfo { } } +#[profiling::all_functions] impl FunctionInfo { /// Create a new function info with default values. pub fn new() -> Self { @@ -108,6 +109,7 @@ pub struct FunctionArgInfo { pub type_info: Option, } +#[profiling::all_functions] impl FunctionArgInfo { /// Create a new function argument info with a name. pub fn with_name(mut self, name: Cow<'static, str>) -> Self { @@ -145,6 +147,7 @@ impl Default for FunctionReturnInfo { } } +#[profiling::all_functions] impl FunctionReturnInfo { /// Create a new function return info for a specific type. pub fn new_for() -> Self { @@ -157,6 +160,7 @@ impl FunctionReturnInfo { macro_rules! impl_documentable { ($( $param:ident ),*) => { + #[profiling::all_functions] impl<$($param,)* F, O> GetFunctionInfo O> for F where F: Fn($($param),*) -> O, diff --git a/crates/bevy_mod_scripting_core/src/lib.rs b/crates/bevy_mod_scripting_core/src/lib.rs index a244130b61..dd16b844f1 100644 --- a/crates/bevy_mod_scripting_core/src/lib.rs +++ b/crates/bevy_mod_scripting_core/src/lib.rs @@ -117,6 +117,7 @@ impl Default for ScriptingPlugin

{ } } +#[profiling::all_functions] impl Plugin for ScriptingPlugin

{ fn build(&self, app: &mut bevy::prelude::App) { app.insert_resource(self.runtime_settings.clone()) diff --git a/crates/bevy_mod_scripting_core/src/runtime.rs b/crates/bevy_mod_scripting_core/src/runtime.rs index 6ddb7050b1..359a7a0c97 100644 --- a/crates/bevy_mod_scripting_core/src/runtime.rs +++ b/crates/bevy_mod_scripting_core/src/runtime.rs @@ -52,6 +52,7 @@ impl Default for RuntimeContainer

{ } } +#[profiling::function] pub(crate) fn initialize_runtime( runtime: ResMut>, settings: Res>, diff --git a/crates/bevy_mod_scripting_core/src/script.rs b/crates/bevy_mod_scripting_core/src/script.rs index c4fd82a5ea..d5b0fe46ae 100644 --- a/crates/bevy_mod_scripting_core/src/script.rs +++ b/crates/bevy_mod_scripting_core/src/script.rs @@ -39,6 +39,7 @@ pub struct Scripts { pub(crate) scripts: HashMap>, } +#[profiling::all_functions] impl Scripts

{ /// Inserts a script into the collection pub fn insert(&mut self, script: Script

) { @@ -113,6 +114,7 @@ pub struct StaticScripts { pub(crate) scripts: HashSet, } +#[profiling::all_functions] impl StaticScripts { /// Inserts a static script into the collection pub fn insert>(&mut self, script: S) { diff --git a/crates/testing_crates/script_integration_test_harness/src/lib.rs b/crates/testing_crates/script_integration_test_harness/src/lib.rs index d9f79fae25..eb3247cf91 100644 --- a/crates/testing_crates/script_integration_test_harness/src/lib.rs +++ b/crates/testing_crates/script_integration_test_harness/src/lib.rs @@ -20,7 +20,9 @@ use bevy::{ }; use bevy_mod_scripting_core::{ asset::ScriptAsset, - bindings::{pretty_print::DisplayWithWorld, script_value::ScriptValue, WorldGuard}, + bindings::{ + pretty_print::DisplayWithWorld, script_value::ScriptValue, WorldAccessGuard, WorldGuard, + }, callback_labels, error::{InteropError, ScriptError}, event::{IntoCallbackLabel, ScriptErrorEvent}, @@ -30,7 +32,9 @@ use bevy_mod_scripting_core::{ IntoScriptPluginParams, ScriptingPlugin, }; use bevy_mod_scripting_functions::ScriptFunctionsPlugin; -use test_functions::register_test_functions; +use criterion::{measurement::Measurement, BatchSize}; +use rand::SeedableRng; +use test_functions::{register_test_functions, RNG}; use test_utils::test_data::setup_integration_test; fn dummy_update_system() {} @@ -318,7 +322,7 @@ pub fn run_lua_benchmark( label: &str, criterion: &mut criterion::BenchmarkGroup, ) -> Result<(), String> { - use bevy::utils::tracing; + use bevy::{log::Level, utils::tracing}; use bevy_mod_scripting_lua::mlua::Function; let plugin = make_test_lua_plugin(); @@ -334,8 +338,8 @@ pub fn run_lua_benchmark( if let Some(pre_bencher) = &pre_bencher { pre_bencher.call::<()>(()).unwrap(); } - tracing::info_span!("profiling_iter", label); c.iter(|| { + tracing::event!(Level::TRACE, "profiling_iter {}", label); bencher.call::<()>(()).unwrap(); }) }); @@ -350,7 +354,7 @@ pub fn run_rhai_benchmark( label: &str, criterion: &mut criterion::BenchmarkGroup, ) -> Result<(), String> { - use bevy::utils::tracing; + use bevy::{log::Level, utils::tracing}; use bevy_mod_scripting_rhai::rhai::Dynamic; let plugin = make_test_rhai_plugin(); @@ -370,9 +374,9 @@ pub fn run_rhai_benchmark( .call_fn::(&mut ctxt.scope, &ctxt.ast, "pre_bench", ARGS) .unwrap(); } - tracing::info_span!("profiling_iter", label); c.iter(|| { + tracing::event!(Level::TRACE, "profiling_iter {}", label); let _ = runtime .call_fn::(&mut ctxt.scope, &ctxt.ast, "bench", ARGS) .unwrap(); @@ -447,7 +451,49 @@ where } state.apply(app.world_mut()); if timer.elapsed() > Duration::from_secs(30) { - return Err("Timeout after 30 seconds".into()); + return Err("Timeout after 30 seconds, could not load script".into()); } } } + +pub fn perform_benchmark_with_generator< + M: Measurement, + I, + G: Fn(&mut rand_chacha::ChaCha12Rng, WorldAccessGuard) -> I, + B: Fn(WorldAccessGuard, I), +>( + label: &str, + generator: &G, + bench_fn: &B, + group: &mut criterion::BenchmarkGroup, + batch_size: BatchSize, +) { + let mut world = std::mem::take(setup_integration_test(|_, _| {}).world_mut()); + + let world_guard = WorldAccessGuard::new_exclusive(&mut world); + let mut rng_guard = RNG.lock().unwrap(); + *rng_guard = rand_chacha::ChaCha12Rng::from_seed([42u8; 32]); + drop(rng_guard); + group.bench_function(label, |c| { + c.iter_batched( + || { + let mut rng_guard = RNG.lock().unwrap(); + unsafe { world_guard.release_all_accesses() }; + { + let allocator = world_guard.allocator(); + let mut allocator = allocator.write(); + allocator.clean_garbage_allocations(); + } + ( + generator(&mut rng_guard, world_guard.clone()), + world_guard.clone(), + ) + }, + |(i, w)| { + bevy::utils::tracing::event!(bevy::log::Level::TRACE, "profiling_iter {}", label); + bench_fn(w, i) + }, + batch_size, + ); + }); +} diff --git a/crates/testing_crates/script_integration_test_harness/src/test_functions.rs b/crates/testing_crates/script_integration_test_harness/src/test_functions.rs index 910ee6c412..ad658c0a62 100644 --- a/crates/testing_crates/script_integration_test_harness/src/test_functions.rs +++ b/crates/testing_crates/script_integration_test_harness/src/test_functions.rs @@ -27,11 +27,13 @@ use rand_chacha::ChaCha12Rng; use test_utils::test_data::EnumerateTestComponents; // lazy lock rng state -static RNG: std::sync::LazyLock> = std::sync::LazyLock::new(|| { +pub static RNG: std::sync::LazyLock> = std::sync::LazyLock::new(|| { let seed = [42u8; 32]; Mutex::new(ChaCha12Rng::from_seed(seed)) }); +pub use rand; + pub fn register_test_functions(world: &mut App) { let world = world.world_mut(); NamespaceBuilder::::new_unregistered(world) diff --git a/crates/testing_crates/test_utils/src/lib.rs b/crates/testing_crates/test_utils/src/lib.rs index ed79df1316..b371f235bb 100644 --- a/crates/testing_crates/test_utils/src/lib.rs +++ b/crates/testing_crates/test_utils/src/lib.rs @@ -45,7 +45,7 @@ fn visit_dirs(dir: &Path, cb: &mut dyn FnMut(&DirEntry)) -> io::Result<()> { Ok(()) } -pub fn discover_all_tests(manifest_dir: PathBuf, filter: impl Fn(&Path) -> bool) -> Vec { +pub fn discover_all_tests(manifest_dir: PathBuf, filter: impl Fn(&Test) -> bool) -> Vec { let assets_root = manifest_dir.join("assets"); let mut test_files = Vec::new(); visit_dirs(&assets_root, &mut |entry| { @@ -60,13 +60,15 @@ pub fn discover_all_tests(manifest_dir: PathBuf, filter: impl Fn(&Path) -> bool) { // only take the path from the assets bit let relative = path.strip_prefix(&assets_root).unwrap(); - if !filter(relative) { - return; - } - test_files.push(Test { + let test = Test { path: relative.to_path_buf(), kind, - }); + }; + + if !filter(&test) { + return; + } + test_files.push(test); } }) .unwrap(); From 9a8ed637e8b6b595d9be27ee754df35ebc294bdb Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 27 Mar 2025 17:17:30 +0000 Subject: [PATCH 2/4] fix compile issue --- tests/script_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/script_tests.rs b/tests/script_tests.rs index 73c7c3995c..cbb451abd6 100644 --- a/tests/script_tests.rs +++ b/tests/script_tests.rs @@ -46,7 +46,7 @@ fn main() { let args = Arguments::from_args(); let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let tests = discover_all_tests(manifest_dir, |p| p.starts_with("tests")) + let tests = discover_all_tests(manifest_dir, |p| p.path.starts_with("tests")) .into_iter() .map(|t| Trial::test(t.name(), move || t.execute())) .collect::>(); From 2be04a98f5aee061bbb82b332d7eb1b71ffaf058 Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 27 Mar 2025 17:26:55 +0000 Subject: [PATCH 3/4] make sure all graphs get re-updated on bencher dev --- crates/xtask/src/main.rs | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index c3ad9fd391..38c38d27d0 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -1417,6 +1417,7 @@ impl Xtasks { .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::inherit()) .args(["plot", "list", "bms"]) + .args(["--per-page", "255"]) .args(["--token", &token.clone().unwrap_or_default()]) .output() .with_context(|| "Could not list plots")?; @@ -1448,31 +1449,18 @@ impl Xtasks { bail!("Failed to delete plot: {:?}", bencher_cmd); } } - let testbeds = Command::new("bencher") - .arg("testbed") - .args(["list", "bms"]) - .args(["--token", &token.clone().unwrap_or_default()]) - .output() - .with_context(|| "Could not list testbeds")?; const MAIN_BRANCH_UUID: &str = "1d70a4e3-d416-43fc-91bd-4b1c8f9e9580"; const LATENCY_MEASURE_UUID: &str = "6820b034-5163-4cdd-95f5-5640dd0ff298"; - - if !testbeds.status.success() { - bail!("Failed to list testbeds: {:?}", testbeds); - } - - let mut testbeds = parse_list_of_dicts(testbeds.stdout) - .with_context(|| "reading testbeds")? - .into_iter() - .map(|p| { - let name = p.get("name").expect("no name in testbed"); - let uuid = p.get("uuid").expect("no uuid in testbed"); - (name.clone(), uuid.clone()) - }) - .filter(|(name, _)| name.contains("gha")) - .collect::>(); - testbeds.sort(); + const LINUX_GHA_TESTBED: &str = "467e8580-a67a-435e-a602-b167541f332c"; + const MACOS_GHA_TESTBAD: &str = "f8aab940-27d2-4b52-93df-4518fe68abfb"; + const WINDOWS_GHA_TESTBED: &str = "be8ff546-31d3-40c4-aacc-763e5e8a09c4"; + + let testbeds = [ + ("linux-gha", LINUX_GHA_TESTBED), + ("macos-gha", MACOS_GHA_TESTBAD), + ("windows-gha", WINDOWS_GHA_TESTBED), + ]; let group_to_benchmark_map: HashMap<_, Vec<_>> = benchmarks From 6517d7e57e9650ec5ab0f36f10c91fba2b4bdfe2 Mon Sep 17 00:00:00 2001 From: makspll Date: Thu, 27 Mar 2025 17:40:04 +0000 Subject: [PATCH 4/4] continue on error for bencher archival --- .github/workflows/bencher_on_pr_or_fork_closed.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bencher_on_pr_or_fork_closed.yml b/.github/workflows/bencher_on_pr_or_fork_closed.yml index 7107cdead4..74d57cf940 100644 --- a/.github/workflows/bencher_on_pr_or_fork_closed.yml +++ b/.github/workflows/bencher_on_pr_or_fork_closed.yml @@ -14,4 +14,5 @@ jobs: bencher archive \ --project bms \ --token '${{ secrets.BENCHER_API_TOKEN }}' \ - --branch "$GITHUB_HEAD_REF" \ No newline at end of file + --branch "$GITHUB_HEAD_REF" + continue-on-error: true \ No newline at end of file