Skip to content

Commit 5b112e9

Browse files
committed
perf: Adjust Grid, StoryBoard and VisualStatGroup enumerations
1 parent e86c5d3 commit 5b112e9

File tree

4 files changed

+62
-23
lines changed

4 files changed

+62
-23
lines changed

src/Uno.UI/UI/Xaml/Controls/Grid/Grid.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,12 @@ void ValidateDefinitions(
192192
bool treatStarAsAuto)
193193
{
194194
//for (auto & cdo : definitions)
195-
foreach(DefinitionBase def in definitions.GetItems())
195+
var itemsEnumerator = definitions.GetItems().GetEnumerator();
196+
197+
while(itemsEnumerator.MoveNext())
196198
{
197-
//var def = (DefinitionBase)(cdo);
199+
var def = itemsEnumerator.Current;
200+
198201
bool useLayoutRounding = GetUseLayoutRounding();
199202
var userSize = double.PositiveInfinity;
200203
var userMinSize = useLayoutRounding
@@ -1066,10 +1069,12 @@ private XSIZEF InnerMeasureOverride(XSIZEF availableSize)
10661069
var children = (GetChildren());
10671070
if (children is { })
10681071
{
1069-
//for (auto & cdo : (children))
1070-
foreach (var currentChild in children)
1072+
// This block is a manual enumeration to avoid the foreach pattern
1073+
// See https://github.com/dotnet/runtime/issues/56309 for details
1074+
var childrenEnumerator = children.GetEnumerator();
1075+
while (childrenEnumerator.MoveNext())
10711076
{
1072-
//var currentChild = (UIElement)(cdo);
1077+
var currentChild = childrenEnumerator.Current;
10731078
ASSERT(currentChild is { });
10741079

10751080
//currentChild.Measure(innerAvailableSize);
@@ -1357,10 +1362,12 @@ private XSIZEF InnerArrangeOverride(XSIZEF finalSize)
13571362
var children = GetChildren();
13581363
if (children is { })
13591364
{
1360-
//for (auto & cdo : (children))
1361-
foreach (var cdo in children)
1365+
// This block is a manual enumeration to avoid the foreach pattern
1366+
// See https://github.com/dotnet/runtime/issues/56309 for details
1367+
var childrenEnumerator = children.GetEnumerator();
1368+
while (childrenEnumerator.MoveNext())
13621369
{
1363-
var currentChild = (UIElement)(cdo);
1370+
var currentChild = childrenEnumerator.Current;
13641371
ASSERT(currentChild is { });
13651372

13661373
//currentChild.EnsureLayoutStorage();

src/Uno.UI/UI/Xaml/Media/Animation/Storyboard.cs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,10 @@ private void Play()
120120
{
121121
if (Children != null && Children.Count > 0)
122122
{
123-
foreach (ITimeline child in Children)
123+
for (int i = 0; i < Children.Count; i++)
124124
{
125+
ITimeline child = Children[i];
126+
125127
DisposeChildRegistrations(child);
126128

127129
_runningChildren++;
@@ -167,8 +169,10 @@ public void Stop()
167169

168170
if (Children != null)
169171
{
170-
foreach (ITimeline child in Children)
172+
for (int i = 0; i < Children.Count; i++)
171173
{
174+
ITimeline child = Children[i];
175+
172176
child.Stop();
173177
DisposeChildRegistrations(child);
174178
}
@@ -192,8 +196,10 @@ public void Resume()
192196
{
193197
State = TimelineState.Active;
194198

195-
foreach (ITimeline child in Children)
199+
for (int i = 0; i < Children.Count; i++)
196200
{
201+
ITimeline child = Children[i];
202+
197203
child.Resume();
198204
}
199205
}
@@ -215,8 +221,10 @@ public void Pause()
215221

216222
if (Children != null)
217223
{
218-
foreach (ITimeline child in Children)
224+
for (int i = 0; i < Children.Count; i++)
219225
{
226+
ITimeline child = Children[i];
227+
220228
child.Pause();
221229
}
222230
}
@@ -226,8 +234,10 @@ public void Seek(TimeSpan offset)
226234
{
227235
if (Children != null)
228236
{
229-
foreach (ITimeline child in Children)
237+
for (int i = 0; i < Children.Count; i++)
230238
{
239+
ITimeline child = Children[i];
240+
231241
child.Seek(offset);
232242
}
233243
}
@@ -237,8 +247,10 @@ public void SeekAlignedToLastTick(TimeSpan offset)
237247
{
238248
if (Children != null)
239249
{
240-
foreach (ITimeline child in Children)
250+
for (int i = 0; i < Children.Count; i++)
241251
{
252+
ITimeline child = Children[i];
253+
242254
child.SeekAlignedToLastTick(offset);
243255
}
244256
}
@@ -247,8 +259,10 @@ public void SkipToFill()
247259
{
248260
if (Children != null)
249261
{
250-
foreach (ITimeline child in Children)
262+
for (int i = 0; i < Children.Count; i++)
251263
{
264+
ITimeline child = Children[i];
265+
252266
child.SkipToFill();
253267
}
254268
}
@@ -261,8 +275,10 @@ internal void Deactivate()
261275

262276
if (Children != null)
263277
{
264-
foreach (ITimeline child in Children)
278+
for (int i = 0; i < Children.Count; i++)
265279
{
280+
ITimeline child = Children[i];
281+
266282
child.Deactivate();
267283
DisposeChildRegistrations(child);
268284
}
@@ -275,8 +291,10 @@ internal void TurnOverAnimationsTo(Storyboard storyboard)
275291
{
276292
var affectedProperties = storyboard.Children.TargetedProperties;
277293

278-
foreach (var child in Children)
294+
for (int i = 0; i < Children.Count; i++)
279295
{
296+
var child = Children[i];
297+
280298
var id = child.GetTimelineTargetFullName();
281299

282300
if (affectedProperties.Contains(id))
@@ -361,9 +379,9 @@ protected override void Dispose(bool disposing)
361379

362380
if (Children != null)
363381
{
364-
foreach (var child in Children)
382+
for (int i = 0; i < Children.Count; i++)
365383
{
366-
child.Dispose();
384+
Children[i].Dispose();
367385
}
368386
}
369387
}

src/Uno.UI/UI/Xaml/UIElementCollection.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,13 @@ public void Clear()
7070
{
7171
var items = ClearCore();
7272

73-
foreach (var item in items)
73+
// This block is a manual enumeration to avoid the foreach pattern
74+
// See https://github.com/dotnet/runtime/issues/56309 for details
75+
var itemsEnumerator = items.GetEnumerator();
76+
while (itemsEnumerator.MoveNext())
7477
{
78+
var item = itemsEnumerator.Current;
79+
7580
if (item is IDependencyObjectStoreProvider provider)
7681
{
7782
item.SetParent(null);

src/Uno.UI/UI/Xaml/VisualStateGroup.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,13 @@ internal void GoToState(
240240
// the value is applied only at the end of the transition
241241
if (current.setters is { } currentSetters)
242242
{
243-
foreach (var setter in currentSetters.OfType<Setter>())
243+
// This block is a manual enumeration to avoid the foreach pattern
244+
// See https://github.com/dotnet/runtime/issues/56309 for details
245+
var settersEnumerator = currentSetters.OfType<Setter>().GetEnumerator();
246+
while(settersEnumerator.MoveNext())
244247
{
248+
var setter = settersEnumerator.Current;
249+
245250
if (element != null && (target.setters?.OfType<Setter>().Any(o => o.HasSameTarget(setter, DependencyPropertyValuePrecedences.Animations, element)) ?? false))
246251
{
247252
// We clear the value of the current setter only if there isn't any setter in the target state
@@ -333,9 +338,13 @@ void ApplyTargetStateSetters()
333338
// We need to invoke them using the right resource context.
334339
ResourceResolver.PushNewScope(_xamlScope);
335340

336-
foreach (var setter in target.setters.OfType<Setter>())
341+
// This block is a manual enumeration to avoid the foreach pattern
342+
// See https://github.com/dotnet/runtime/issues/56309 for details
343+
var settersEnumerator = target.setters.OfType<Setter>().GetEnumerator();
344+
345+
while(settersEnumerator.MoveNext())
337346
{
338-
setter.ApplyValue(DependencyPropertyValuePrecedences.Animations, element);
347+
settersEnumerator.Current.ApplyValue(DependencyPropertyValuePrecedences.Animations, element);
339348
}
340349
}
341350
#if !HAS_EXPENSIVE_TRYFINALLY

0 commit comments

Comments
 (0)