File tree Expand file tree Collapse file tree
Screens/Play/HUD/HitErrorMeters Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -102,10 +102,25 @@ protected override void Update()
102102 {
103103 // We need to use lifetime entries to find the next object (we can't just use `hitObjectContainer.Objects` due to pooling - it may even be empty).
104104 // If required, we can make this lookup more efficient by adding support to get next-future-entry in LifetimeEntryManager.
105- var candidate =
106- // Use alive entries first as an optimisation.
107- hitObjectContainer . AliveEntries . Keys . Where ( e => ! isAlreadyHit ( e ) ) . MinBy ( e => e . HitObject . StartTime )
108- ?? hitObjectContainer . Entries . Where ( e => ! isAlreadyHit ( e ) ) . MinBy ( e => e . HitObject . StartTime ) ;
105+
106+ // Use alive entries first as an optimisation (single-pass minimum, no LINQ allocation).
107+ HitObjectLifetimeEntry ? candidate = null ;
108+
109+ foreach ( var e in hitObjectContainer . AliveEntries . Keys )
110+ {
111+ if ( ! isAlreadyHit ( e ) && ( candidate == null || e . HitObject . StartTime < candidate . HitObject . StartTime ) )
112+ candidate = e ;
113+ }
114+
115+ // Fall back to full entries if no alive non-judged entry found.
116+ if ( candidate == null )
117+ {
118+ foreach ( var e in hitObjectContainer . Entries )
119+ {
120+ if ( ! isAlreadyHit ( e ) && ( candidate == null || e . HitObject . StartTime < candidate . HitObject . StartTime ) )
121+ candidate = e ;
122+ }
123+ }
109124
110125 // In the case there are no non-judged objects, the last hit object should be used instead.
111126 if ( candidate == null )
Original file line number Diff line number Diff line change @@ -115,10 +115,32 @@ public void Push(HitErrorShape shape)
115115
116116 private void removeExtraJudgements ( )
117117 {
118- var remainingChildren = Children . Where ( c => ! c . IsRemoved ) ;
118+ // Count non-removed children and remove excess starting from the oldest.
119+ // This avoids re-enumerating via LINQ .Count()/.First() on every iteration.
120+ int remaining = 0 ;
119121
120- while ( remainingChildren . Count ( ) > JudgementCount . Value )
121- remainingChildren . First ( ) . Remove ( ) ;
122+ foreach ( var c in Children )
123+ {
124+ if ( ! c . IsRemoved )
125+ remaining ++ ;
126+ }
127+
128+ int target = JudgementCount . Value ;
129+
130+ if ( remaining <= target )
131+ return ;
132+
133+ foreach ( var c in Children )
134+ {
135+ if ( remaining <= target )
136+ break ;
137+
138+ if ( ! c . IsRemoved )
139+ {
140+ c . Remove ( ) ;
141+ remaining -- ;
142+ }
143+ }
122144 }
123145
124146 private void updateMetrics ( )
You can’t perform that action at this time.
0 commit comments