diff --git a/Content.Benchmarks/ComponentQueryBenchmark.cs b/Content.Benchmarks/ComponentQueryBenchmark.cs index 49e9984c09..bfe367790a 100644 --- a/Content.Benchmarks/ComponentQueryBenchmark.cs +++ b/Content.Benchmarks/ComponentQueryBenchmark.cs @@ -29,7 +29,7 @@ namespace Content.Benchmarks; [CategoriesColumn] public class ComponentQueryBenchmark { - public const string Map = "Maps/atlas.yml"; + public const string Map = "Maps/saltern.yml"; private TestPair _pair = default!; private IEntityManager _entMan = default!; diff --git a/Content.Benchmarks/Program.cs b/Content.Benchmarks/Program.cs index 42a436597d..6f1f4e6f19 100644 --- a/Content.Benchmarks/Program.cs +++ b/Content.Benchmarks/Program.cs @@ -1,15 +1,7 @@ using System; -using System.Linq; -using System.Threading.Tasks; using BenchmarkDotNet.Running; -using Content.IntegrationTests; -using Content.Server.Maps; -#if DEBUG using BenchmarkDotNet.Configs; -#else using Robust.Benchmarks.Configs; -#endif -using Robust.Shared.Prototypes; namespace Content.Benchmarks { @@ -22,11 +14,15 @@ namespace Content.Benchmarks Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\nWARNING: YOU ARE RUNNING A DEBUG BUILD, USE A RELEASE BUILD FOR AN ACCURATE BENCHMARK"); Console.WriteLine("THE DEBUG BUILD IS ONLY GOOD FOR FIXING A CRASHING BENCHMARK\n"); - BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig()); + var baseConfig = new DebugInProcessConfig(); #else - var config = Environment.GetEnvironmentVariable("ROBUST_BENCHMARKS_ENABLE_SQL") != null ? DefaultSQLConfig.Instance : null; - BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); + var baseConfig = Environment.GetEnvironmentVariable("ROBUST_BENCHMARKS_ENABLE_SQL") != null + ? DefaultSQLConfig.Instance + : DefaultConfig.Instance; #endif + var config = ManualConfig.Create(baseConfig); + config.BuildTimeout = TimeSpan.FromMinutes(5); + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); } } } diff --git a/Content.Benchmarks/RaiseEventBenchmark.cs b/Content.Benchmarks/RaiseEventBenchmark.cs new file mode 100644 index 0000000000..4c4e0d9125 --- /dev/null +++ b/Content.Benchmarks/RaiseEventBenchmark.cs @@ -0,0 +1,126 @@ +#nullable enable +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Content.IntegrationTests; +using Content.IntegrationTests.Pair; +using Robust.Shared; +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; + +namespace Content.Benchmarks; + +[Virtual] +public class RaiseEventBenchmark +{ + private TestPair _pair = default!; + private BenchSystem _sys = default!; + + [GlobalSetup] + public void Setup() + { + ProgramShared.PathOffset = "../../../../"; + PoolManager.Startup(typeof(BenchSystem).Assembly); + _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); + var entMan = _pair.Server.EntMan; + _sys = entMan.System(); + + _pair.Server.WaitPost(() => + { + var uid = entMan.Spawn(); + _sys.Ent = new(uid, entMan.GetComponent(uid)); + _sys.Ent2 = new(_sys.Ent.Owner, _sys.Ent.Comp); + }) + .GetAwaiter() + .GetResult(); + } + + [GlobalCleanup] + public async Task Cleanup() + { + await _pair.DisposeAsync(); + PoolManager.Shutdown(); + } + + [Benchmark(Baseline = true)] + public int RaiseEvent() + { + return _sys.RaiseEvent(); + } + + [Benchmark] + public int RaiseCompEvent() + { + return _sys.RaiseCompEvent(); + } + + [Benchmark] + public int RaiseICompEvent() + { + return _sys.RaiseICompEvent(); + } + + [Benchmark] + public int RaiseCSharpEvent() + { + return _sys.CSharpEvent(); + } + + public sealed class BenchSystem : EntitySystem + { + public Entity Ent; + public Entity Ent2; + + public delegate void EntityEventHandler(EntityUid uid, TransformComponent comp, ref BenchEv ev); + + public event EntityEventHandler? OnCSharpEvent; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnEvent); + OnCSharpEvent += OnEvent; + } + + public int RaiseEvent() + { + var ev = new BenchEv(); + RaiseLocalEvent(Ent.Owner, ref ev); + return ev.N; + } + + public int RaiseCompEvent() + { + var ev = new BenchEv(); + EntityManager.EventBus.RaiseComponentEvent(Ent.Owner, Ent.Comp, ref ev); + return ev.N; + } + + public int RaiseICompEvent() + { + // Raise with an IComponent instead of concrete type + var ev = new BenchEv(); + EntityManager.EventBus.RaiseComponentEvent(Ent2.Owner, Ent2.Comp, ref ev); + return ev.N; + } + + public int CSharpEvent() + { + var ev = new BenchEv(); + OnCSharpEvent?.Invoke(Ent.Owner, Ent.Comp, ref ev); + return ev.N; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void OnEvent(EntityUid uid, TransformComponent component, ref BenchEv args) + { + args.N += uid.Id; + } + + [ByRefEvent] + public struct BenchEv + { + public int N; + } + } +}