diff --git a/osu.Game.Benchmarks/BenchmarkRuleset.cs b/osu.Game.Benchmarks/BenchmarkRuleset.cs new file mode 100644 index 0000000000..63c99dcb2b --- /dev/null +++ b/osu.Game.Benchmarks/BenchmarkRuleset.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using osu.Game.Online.API; +using osu.Game.Rulesets.Osu; + +namespace osu.Game.Benchmarks +{ + public class BenchmarkRuleset : BenchmarkTest + { + private OsuRuleset ruleset; + private APIMod apiModDoubleTime; + private APIMod apiModDifficultyAdjust; + + public override void SetUp() + { + base.SetUp(); + ruleset = new OsuRuleset(); + apiModDoubleTime = new APIMod { Acronym = "DT" }; + apiModDifficultyAdjust = new APIMod { Acronym = "DA" }; + } + + [Benchmark] + public void BenchmarkToModDoubleTime() + { + apiModDoubleTime.ToMod(ruleset); + } + + [Benchmark] + public void BenchmarkToModDifficultyAdjust() + { + apiModDifficultyAdjust.ToMod(ruleset); + } + + [Benchmark] + public void BenchmarkGetAllMods() + { + ruleset.GetAllMods().Consume(new Consumer()); + } + } +} diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index f373e59417..5db502804d 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -4,6 +4,7 @@ #nullable enable using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -167,9 +168,21 @@ namespace osu.Game.Configuration } } + private static readonly ConcurrentDictionary property_info_cache = new ConcurrentDictionary(); + public static IEnumerable<(SettingSourceAttribute, PropertyInfo)> GetSettingsSourceProperties(this object obj) { - foreach (var property in obj.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) + var type = obj.GetType(); + + if (!property_info_cache.TryGetValue(type, out var properties)) + property_info_cache[type] = properties = getSettingsSourceProperties(type).ToArray(); + + return properties; + } + + private static IEnumerable<(SettingSourceAttribute, PropertyInfo)> getSettingsSourceProperties(Type type) + { + foreach (var property in type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) { var attr = property.GetCustomAttribute(true);