From f948f8ee5c49498ea58fe2a2e5817ef7fbb027c7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 25 Feb 2024 17:59:20 +0300 Subject: [PATCH 1/4] Fix HUDOverlay allocations --- osu.Game/Screens/Play/HUDOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 32ebb82f15..f965d3392a 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -258,13 +258,13 @@ protected override void Update() Vector2? highestBottomScreenSpace = null; - foreach (var element in mainComponents.Components) - processDrawable(element); + for (int i = 0; i < mainComponents.Components.Count; i++) + processDrawable(mainComponents.Components[i]); if (rulesetComponents != null) { - foreach (var element in rulesetComponents.Components) - processDrawable(element); + for (int i = 0; i < rulesetComponents.Components.Count; i++) + processDrawable(rulesetComponents.Components[i]); } if (lowestTopScreenSpaceRight.HasValue) From c3fa97d062c370c4d5c60b2cee66e7b8298a79b7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 25 Feb 2024 18:02:42 +0300 Subject: [PATCH 2/4] Reduce allocations in HitObjectLifetimeEntry --- .../Rulesets/Objects/HitObjectLifetimeEntry.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs index 4450f026b4..9f2720b7ca 100644 --- a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs +++ b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs @@ -41,7 +41,22 @@ public class HitObjectLifetimeEntry : LifetimeEntry /// /// Whether and all of its nested objects have been judged. /// - public bool AllJudged => Judged && NestedEntries.All(h => h.AllJudged); + public bool AllJudged + { + get + { + if (!Judged) + return false; + + foreach (var entry in NestedEntries) + { + if (!entry.AllJudged) + return false; + } + + return true; + } + } private readonly IBindable startTimeBindable = new BindableDouble(); From 9e3defebda1d446f815cb0cae6618f822ba482d2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 25 Feb 2024 19:05:40 +0300 Subject: [PATCH 3/4] Remove unused using --- osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs index 9f2720b7ca..4962ac13b5 100644 --- a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs +++ b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Performance; using osu.Game.Rulesets.Judgements; From 4421ff975b330e832ee0405b9171dfeed2255577 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Feb 2024 09:04:39 +0800 Subject: [PATCH 4/4] Add local function to perform iteration to better explain the "why" --- osu.Game/Screens/Play/HUDOverlay.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index f965d3392a..2ec2a011a6 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -258,14 +258,10 @@ protected override void Update() Vector2? highestBottomScreenSpace = null; - for (int i = 0; i < mainComponents.Components.Count; i++) - processDrawable(mainComponents.Components[i]); + processDrawables(mainComponents); if (rulesetComponents != null) - { - for (int i = 0; i < rulesetComponents.Components.Count; i++) - processDrawable(rulesetComponents.Components[i]); - } + processDrawables(rulesetComponents); if (lowestTopScreenSpaceRight.HasValue) topRightElements.Y = MathHelper.Clamp(ToLocalSpace(new Vector2(0, lowestTopScreenSpaceRight.Value)).Y, 0, DrawHeight - topRightElements.DrawHeight); @@ -282,6 +278,14 @@ protected override void Update() else bottomRightElements.Y = 0; + void processDrawables(SkinComponentsContainer components) + { + // Avoid using foreach due to missing GetEnumerator implementation. + // See https://github.com/ppy/osu-framework/blob/e10051e6643731e393b09de40a3a3d209a545031/osu.Framework/Bindables/IBindableList.cs#L41-L44. + for (int i = 0; i < components.Components.Count; i++) + processDrawable(components.Components[i]); + } + void processDrawable(ISerialisableDrawable element) { // Cast can be removed when IDrawable interface includes Anchor / RelativeSizeAxes.