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 @@ protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(I
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
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>()
.OrderBy(x => x.StartTime))
{

View File

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