1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 15:43:21 +08:00

Reduce NestedHitObject enumerator overhead

This was especially bad due to it allocating on any and every start time
change, even the first (see usage in `HitObject.ctor`).
This commit is contained in:
Dean Herbert 2021-09-20 01:48:33 +09:00
parent 0d58530dbe
commit 16e60eed56
2 changed files with 12 additions and 8 deletions

View File

@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream. // In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
foreach (var hitObject in beatmap.HitObjects foreach (var hitObject in beatmap.HitObjects
.SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects : new[] { obj }) .SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects.AsEnumerable() : new[] { obj })
.Cast<CatchHitObject>() .Cast<CatchHitObject>()
.OrderBy(x => x.StartTime)) .OrderBy(x => x.StartTime))
{ {

View File

@ -3,11 +3,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.ListExtensions;
using osu.Framework.Lists;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
@ -83,7 +84,7 @@ namespace osu.Game.Rulesets.Objects
private readonly List<HitObject> nestedHitObjects = new List<HitObject>(); private readonly List<HitObject> nestedHitObjects = new List<HitObject>();
[JsonIgnore] [JsonIgnore]
public IReadOnlyList<HitObject> NestedHitObjects => nestedHitObjects; public SlimReadOnlyListWrapper<HitObject> NestedHitObjects => nestedHitObjects.AsSlimReadOnly();
public HitObject() public HitObject()
{ {
@ -91,7 +92,7 @@ namespace osu.Game.Rulesets.Objects
{ {
double offset = time.NewValue - time.OldValue; double offset = time.NewValue - time.OldValue;
foreach (var nested in NestedHitObjects) foreach (var nested in nestedHitObjects)
nested.StartTime += offset; nested.StartTime += offset;
}; };
} }
@ -122,11 +123,14 @@ namespace osu.Game.Rulesets.Objects
if (this is IHasComboInformation hasCombo) if (this is IHasComboInformation hasCombo)
{ {
foreach (var n in NestedHitObjects.OfType<IHasComboInformation>()) foreach (HitObject hitObject in nestedHitObjects)
{ {
n.ComboIndexBindable.BindTo(hasCombo.ComboIndexBindable); if (hitObject is IHasComboInformation n)
n.ComboIndexWithOffsetsBindable.BindTo(hasCombo.ComboIndexWithOffsetsBindable); {
n.IndexInCurrentComboBindable.BindTo(hasCombo.IndexInCurrentComboBindable); n.ComboIndexBindable.BindTo(hasCombo.ComboIndexBindable);
n.ComboIndexWithOffsetsBindable.BindTo(hasCombo.ComboIndexWithOffsetsBindable);
n.IndexInCurrentComboBindable.BindTo(hasCombo.IndexInCurrentComboBindable);
}
} }
} }