1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 08:27:49 +08:00

Merge pull request #27173 from EVAST9919/song-select-sort

Reduce allocations during aggregate beatmap sorts in song-select screen
This commit is contained in:
Dean Herbert 2024-02-15 12:50:16 +08:00 committed by GitHub
commit 728f65b6d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 8 deletions

View File

@ -91,19 +91,19 @@ namespace osu.Game.Screens.Select.Carousel
break; break;
case SortMode.LastPlayed: case SortMode.LastPlayed:
comparison = -compareUsingAggregateMax(otherSet, b => (b.LastPlayed ?? DateTimeOffset.MinValue).ToUnixTimeSeconds()); comparison = -compareUsingAggregateMax(otherSet, static b => (b.LastPlayed ?? DateTimeOffset.MinValue).ToUnixTimeSeconds());
break; break;
case SortMode.BPM: case SortMode.BPM:
comparison = compareUsingAggregateMax(otherSet, b => b.BPM); comparison = compareUsingAggregateMax(otherSet, static b => b.BPM);
break; break;
case SortMode.Length: case SortMode.Length:
comparison = compareUsingAggregateMax(otherSet, b => b.Length); comparison = compareUsingAggregateMax(otherSet, static b => b.Length);
break; break;
case SortMode.Difficulty: case SortMode.Difficulty:
comparison = compareUsingAggregateMax(otherSet, b => b.StarRating); comparison = compareUsingAggregateMax(otherSet, static b => b.StarRating);
break; break;
case SortMode.DateSubmitted: case SortMode.DateSubmitted:
@ -127,12 +127,40 @@ namespace osu.Game.Screens.Select.Carousel
/// <summary> /// <summary>
/// All beatmaps which are not filtered and valid for display. /// All beatmaps which are not filtered and valid for display.
/// </summary> /// </summary>
protected IEnumerable<BeatmapInfo> ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value || b.State.Value == CarouselItemState.Selected).Select(b => b.BeatmapInfo); protected IEnumerable<BeatmapInfo> ValidBeatmaps
{
get
{
foreach (var item in Items) // iterating over Items directly to not allocate 2 enumerators
{
if (item is CarouselBeatmap b && (!b.Filtered.Value || b.State.Value == CarouselItemState.Selected))
yield return b.BeatmapInfo;
}
}
}
/// <summary>
/// Whether there are available beatmaps which are not filtered and valid for display.
/// Cheaper alternative to <see cref="ValidBeatmaps"/>.Any()
/// </summary>
public bool HasValidBeatmaps
{
get
{
foreach (var item in Items) // iterating over Items directly to not allocate 2 enumerators
{
if (item is CarouselBeatmap b && (!b.Filtered.Value || b.State.Value == CarouselItemState.Selected))
return true;
}
return false;
}
}
private int compareUsingAggregateMax(CarouselBeatmapSet other, Func<BeatmapInfo, double> func) private int compareUsingAggregateMax(CarouselBeatmapSet other, Func<BeatmapInfo, double> func)
{ {
bool ourBeatmaps = ValidBeatmaps.Any(); bool ourBeatmaps = HasValidBeatmaps;
bool otherBeatmaps = other.ValidBeatmaps.Any(); bool otherBeatmaps = other.HasValidBeatmaps;
if (!ourBeatmaps && !otherBeatmaps) return 0; if (!ourBeatmaps && !otherBeatmaps) return 0;
if (!ourBeatmaps) return -1; if (!ourBeatmaps) return -1;

View File

@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Extensions.ListExtensions;
using osu.Framework.Lists;
namespace osu.Game.Screens.Select.Carousel namespace osu.Game.Screens.Select.Carousel
{ {
@ -12,7 +14,7 @@ namespace osu.Game.Screens.Select.Carousel
{ {
public override DrawableCarouselItem? CreateDrawableRepresentation() => null; public override DrawableCarouselItem? CreateDrawableRepresentation() => null;
public IReadOnlyList<CarouselItem> Items => items; public SlimReadOnlyListWrapper<CarouselItem> Items => items.AsSlimReadOnly();
public int TotalItemsNotFiltered { get; private set; } public int TotalItemsNotFiltered { get; private set; }