| File: Internals\ProfilePage.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
#nullable disable #nullable disable using System; using System.Collections.Generic; using System.Text; using Microsoft.Maui.Controls; using Microsoft.Maui.Controls.Internals; namespace Microsoft.Maui.Controls.Internals { /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="Type[@FullName='Microsoft.Maui.Controls.Internals.ProfileDatum']/Docs/*" /> public class ProfileDatum { /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='Name']/Docs/*" /> public string Name; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='Id']/Docs/*" /> public string Id; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='Ticks']/Docs/*" /> public long Ticks; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='SubTicks']/Docs/*" /> public long SubTicks; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='Depth']/Docs/*" /> public int Depth; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='Path']/Docs/*" /> public string Path; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ProfileDatum.xml" path="//Member[@MemberName='Line']/Docs/*" /> public int Line; } /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ContentPageEx.xml" path="Type[@FullName='Microsoft.Maui.Controls.Internals.ContentPageEx']/Docs/*" /> public static class ContentPageEx { const long MS = TimeSpan.TicksPerMillisecond; /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ContentPageEx.xml" path="//Member[@MemberName='Data']/Docs/*" /> public static List<ProfileDatum> Data = new List<ProfileDatum>(); private static void ASSERT(bool condition) { if (!condition) throw new Exception("assert"); } private static long GatherTicks(ref int i) { var current = Data[i++]; var depth = current.Depth; var total = current.Ticks; while (i < Data.Count) { var next = Data[i]; if (next.Depth < depth) break; if (next.Depth > depth) { current.SubTicks = GatherTicks(ref i); ASSERT(current.Ticks >= current.SubTicks); continue; } i++; current = next; total += current.Ticks; } return total; } private static void AppendProfile(StringBuilder sb, long profiledMs, bool showZeros) { foreach (var datum in Data) { var depth = datum.Depth; var name = datum.Name; if (datum.Id != null) name += $" ({datum.Id})"; var ticksMs = datum.Ticks / MS; var exclusiveTicksMs = (datum.Ticks - datum.SubTicks) / MS; var percentage = (int)Math.Round(ticksMs / (double)profiledMs * 100); if (!showZeros && percentage == 0) continue; var line = $"{name} = {ticksMs}ms"; if (exclusiveTicksMs != ticksMs) line += $" ({exclusiveTicksMs}ms)"; line += $", {percentage}%"; sb.AppendLine("".PadLeft(depth * 2) + line); } } /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/ContentPageEx.xml" path="//Member[@MemberName='LoadProfile']/Docs/*" /> public static void LoadProfile(this ContentPage page) { Profile.Stop(); foreach (var datum in Profile.Data) { Data.Add(new ProfileDatum() { Name = datum.Name, Id = datum.Id, Depth = datum.Depth, Ticks = datum.Ticks < 0 ? 0L : (long)datum.Ticks }); } var i = 0; var profiledMs = GatherTicks(ref i) / MS; var scrollView = new ScrollView(); var label = new Label(); var controls = new Grid(); var buttonA = new Button() { Text = "0s", HeightRequest = 62 }; controls.Add(buttonA); var grid = new Grid { RowDefinitions = new RowDefinitionCollection { new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }, new RowDefinition { Height = GridLength.Auto }, }, ColumnDefinitions = new ColumnDefinitionCollection { new ColumnDefinition { Width = GridLength.Star }, } }; page.Content = grid; grid.Add(scrollView, 0, 0); grid.Add(controls, 0, 1); scrollView.Content = label; var showZeros = false; Action update = delegate () { var sb = new StringBuilder(); sb.AppendLine($"Profiled: {profiledMs}ms"); AppendProfile(sb, profiledMs, showZeros); label.Text = sb.ToString(); }; buttonA.Clicked += delegate { showZeros = !showZeros; update(); }; update(); } } }