Skip to content

perf: reduce allocations in beatmap conversion, playable bounds, and HUD components - #345

Merged
winnerspiros merged 7 commits into
masterfrom
copilot/optimize-performance-and-latency-again
May 21, 2026
Merged

perf: reduce allocations in beatmap conversion, playable bounds, and HUD components#345
winnerspiros merged 7 commits into
masterfrom
copilot/optimize-performance-and-latency-again

Conversation

Copilot AI commented May 21, 2026

Copy link
Copy Markdown

…ng when OverlayActivationMode is wrong

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/b0503980-c181-4806-a9b6-a2b891be69df

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
@gitar-bot

gitar-bot Bot commented May 21, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

Copilot AI and others added 3 commits May 21, 2026 07:21
- OsuFramedReplayInputHandler.IsImportant: frame.Actions.Any() →
  frame.Actions.Count > 0 (called every replay frame; removes enumerator alloc)

- SpeedEvaluator.EvaluateDifficultyOf: mods.OfType<OsuModAutopilot>().Any()
  → inline for-loop with early break (called per note in difficulty calc)

- RhythmEvaluator.EvaluateDifficultyOf: replaced double-scan pattern
  (FirstOrDefault + IndexOf, two O(n) passes) with a single indexed for-loop
  that finds and mutates the entry in one pass

- OsuDifficultyCalculator.CreateDifficultyAttributes: replaced three
  separate beatmap.HitObjects.Count(h => h is T) calls (three full
  enumerations) with a single switch-based loop; also replaced four
  skills.OfType<T>().Single/SingleOrDefault() calls with a single typed loop

- OsuDifficultyCalculator.CreateSkills: mods.Any(h => h is OsuModFlashlight)
  → inline for-loop with early break

- OsuAutoGenerator.addHitObjectClickFrames: previousActions.Any() →
  .Count > 0; frame.Actions.SequenceEqual(previousActions) → new static
  ActionsEqual helper (avoids IEnumerable allocation on every frame)

Removed now-unused 'using System.Linq' from all changed files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…erhead

- AndroidMouseHandler/StylusHandler/KeyboardHandler: add volatile bool
  cachedEnabled field (mirror of Enabled.Value via BindValueChanged),
  matching the existing cachedSensitivity/cachedPressureThreshold/
  TreatAsTouch pattern. The OS dispatch thread now reads a direct volatile
  field instead of traversing the Bindable<bool> property chain on every
  MotionEvent/KeyEvent. The volatile write-then-read guarantees the same
  cross-thread visibility that a BindValueChanged-to-Update-thread would
  provide for the enable/disable path.

- OsuGameAndroid: add adpfDrawThread/adpfUpdateThread/adpfInputThread
  GameThread? fields, assigned once when each ADPF hint session is created
  (on the respective game thread). The three per-frame FrameCompleted
  callbacks (onDrawFrameCompleted, onUpdateFrameCompleted,
  onInputFrameCompleted) now read adpf*Thread?.Clock.ElapsedFrameTime
  instead of Host?.DrawThread?.Clock.ElapsedFrameTime, removing two levels
  of nullable chain traversal per call. At 120 Hz × 3 threads these
  callbacks fire ~360 times/second, so eliminating the Host and *Thread
  property accesses is a measurable reduction in per-frame bookkeeping cost.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
…HUD components

- BeatmapConverter: replace OrderBy().ToList() with in-place List<T>.Sort()
  to avoid creating an intermediate IOrderedEnumerable and a second list.

- IBeatmap.CalculatePlayableBounds: collapse three separate LINQ enumerations
  (Any, Max, First) into a single foreach loop. Reduces from O(3n) to O(n)
  and eliminates two LINQ iterator allocations on every call site.

- PausableSkinnableSound.Length: previously evaluated DrawableSamples twice
  (once for Any(), once for Max()), creating two LINQ chains. Replaced with
  a single foreach that accumulates the maximum sample length.

- JudgementCounter, JudgementCounterDisplay, ArgonJudgementCounter,
  ArgonJudgementCounterDisplay: replaced Types.First() with direct Types[0]
  array indexing and removed the now-unused 'using System.Linq' imports.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
… in ranked rooms)

Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/27570109-9bbd-46a9-bb06-b8e5b4034215

Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
Copilot AI requested a review from winnerspiros May 21, 2026 07:47
Comment thread osu.Game.Rulesets.Osu/Difficulty/Evaluators/SpeedEvaluator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Difficulty/Evaluators/SpeedEvaluator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Difficulty/Evaluators/SpeedEvaluator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Difficulty/Evaluators/SpeedEvaluator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Difficulty/Evaluators/SpeedEvaluator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs Fixed
Comment thread osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs Fixed
Copilot AI requested a review from winnerspiros May 21, 2026 08:32
@winnerspiros
winnerspiros marked this pull request as ready for review May 21, 2026 12:48
Copilot AI review requested due to automatic review settings May 21, 2026 12:48
@winnerspiros
winnerspiros merged commit 44aa5c7 into master May 21, 2026
13 of 25 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants