-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[layout] avoid IView[] creation in LayoutExtensions #8250
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,23 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Microsoft.Maui.Handlers | ||
{ | ||
internal static class LayoutExtensions | ||
{ | ||
record ViewAndIndex(IView View, int Index); | ||
public static IOrderedEnumerable<IView> OrderByZIndex(this ILayout layout) => layout.OrderBy(v => v.ZIndex); | ||
|
||
class ZIndexComparer : IComparer<ViewAndIndex> | ||
{ | ||
public int Compare(ViewAndIndex? x, ViewAndIndex? y) | ||
{ | ||
if (x == null || y == null) | ||
{ | ||
return 0; | ||
} | ||
|
||
var zIndexCompare = x.View.ZIndex.CompareTo(y.View.ZIndex); | ||
|
||
if (zIndexCompare == 0) | ||
{ | ||
return x.Index.CompareTo(y.Index); | ||
} | ||
|
||
return zIndexCompare; | ||
} | ||
} | ||
|
||
static ZIndexComparer s_comparer = new(); | ||
|
||
public static IView[] OrderByZIndex(this ILayout layout) | ||
public static int GetLayoutHandlerIndex(this ILayout layout, IView view) | ||
{ | ||
var count = layout.Count; | ||
var indexedViews = new ViewAndIndex[count]; | ||
|
||
for (int n = 0; n < count; n++) | ||
switch (layout.Count) | ||
{ | ||
indexedViews[n] = new ViewAndIndex(layout[n], n); | ||
case 0: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I bet this is a huge chunk of the performance gain. |
||
return -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. was it returning -1 before ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. |
||
case 1: | ||
return view == layout[0] ? 0 : -1; | ||
default: | ||
return layout.OrderByZIndex().IndexOf(view); | ||
} | ||
|
||
Array.Sort(indexedViews, s_comparer); | ||
|
||
var ordered = new IView[count]; | ||
|
||
for (int n = 0; n < count; n++) | ||
{ | ||
ordered[n] = indexedViews[n].View; | ||
} | ||
|
||
return ordered; | ||
} | ||
|
||
public static int GetLayoutHandlerIndex(this ILayout layout, IView view) | ||
{ | ||
return layout.OrderByZIndex().IndexOf(view); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that a regular
OrderBy()
is the same as this logic. Let me know if I'm missing something, thanks!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I only wrote it the hard way because otherwise I'd have to argue with people about the Linq :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found other places where performance matters, that used
OrderBy()
:https://github.com/dotnet/msbuild/blob/c2ec5c98a76a5496a36025b3f5e790cca6ea3b2f/src/Build/Evaluation/LazyItemEvaluator.cs#L511-L515
This is used when MSBuild evaluates a project, for every type of item group in a build. It would be called when VS loads a project.