Enhance Profiler with memory allocation metrics

This commit is contained in:
max
2026-08-05 13:25:14 +02:00
parent 7853a768de
commit d9582aecdd
2 changed files with 58 additions and 23 deletions
+30 -18
View File
@@ -13,7 +13,7 @@ namespace Nerfed.Editor.Systems
private int selectedFrame = 0;
private int previousSelectedFrame = -1;
private IOrderedEnumerable<KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms)>> orderedCombinedData = null;
private IOrderedEnumerable<KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms, long allocBytes, long selfAllocBytes)>> orderedCombinedData = null;
private IOrderedEnumerable<KeyValuePair<int, Profiler.RollingThreadMetrics>> orderedThreadRollingData = null;
private readonly ProfilerVisualizer.TimelineState timelineState = new ProfilerVisualizer.TimelineState();
private readonly List<Profiler.Frame> frameSnapshot = new List<Profiler.Frame>(256);
@@ -143,14 +143,16 @@ namespace Nerfed.Editor.Systems
ImGui.BeginChild("Hierachy", new Vector2(150, 0), ImGuiChildFlags.ResizeX);
if (ImGui.BeginTable("ProfilerData", 6, tableFlags, new Vector2(0, 0)))
if (ImGui.BeginTable("ProfilerData", 8, tableFlags, new Vector2(0, 0)))
{
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthStretch, 0.40f, 0);
ImGui.TableSetupColumn("category", ImGuiTableColumnFlags.WidthStretch, 0.15f, 1);
ImGui.TableSetupColumn("tags", ImGuiTableColumnFlags.WidthStretch, 0.10f, 2);
ImGui.TableSetupColumn("thread", ImGuiTableColumnFlags.WidthStretch, 0.10f, 3);
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthStretch, 0.30f, 0);
ImGui.TableSetupColumn("category", ImGuiTableColumnFlags.WidthStretch, 0.12f, 1);
ImGui.TableSetupColumn("tags", ImGuiTableColumnFlags.WidthStretch, 0.08f, 2);
ImGui.TableSetupColumn("thread", ImGuiTableColumnFlags.WidthStretch, 0.08f, 3);
ImGui.TableSetupColumn("ms", ImGuiTableColumnFlags.WidthStretch, 0.10f, 4);
ImGui.TableSetupColumn("self", ImGuiTableColumnFlags.WidthStretch, 0.10f, 5);
ImGui.TableSetupColumn("alloc(B)", ImGuiTableColumnFlags.WidthStretch, 0.11f, 6);
ImGui.TableSetupColumn("self alloc", ImGuiTableColumnFlags.WidthStretch, 0.11f, 7);
ImGui.TableSetupScrollFreeze(0, 1); // Make row always visible
ImGui.TableHeadersRow();
@@ -191,6 +193,10 @@ namespace Nerfed.Editor.Systems
ImGui.Text($"{node.ElapsedMilliseconds():0.000}");
ImGui.TableNextColumn();
ImGui.Text($"{node.SelfMilliseconds():0.000}");
ImGui.TableNextColumn();
ImGui.Text($"{node.AllocatedBytes}");
ImGui.TableNextColumn();
ImGui.Text($"{node.SelfAllocatedBytes()}");
if (isOpen)
{
@@ -202,7 +208,7 @@ namespace Nerfed.Editor.Systems
}
}
private static void DrawCombined(in IOrderedEnumerable<KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms)>> orderedCombinedData)
private static void DrawCombined(in IOrderedEnumerable<KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms, long allocBytes, long selfAllocBytes)>> orderedCombinedData)
{
if(orderedCombinedData == null)
{
@@ -211,18 +217,20 @@ namespace Nerfed.Editor.Systems
ImGui.BeginChild("Combined", new Vector2(0, 0));
if (ImGui.BeginTable("ProfilerCombinedData", 6, tableFlags, new Vector2(0, 0)))
if (ImGui.BeginTable("ProfilerCombinedData", 8, tableFlags, new Vector2(0, 0)))
{
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthStretch, 0.45f, 0);
ImGui.TableSetupColumn("ms", ImGuiTableColumnFlags.WidthStretch, 0.14f, 1);
ImGui.TableSetupColumn("self", ImGuiTableColumnFlags.WidthStretch, 0.14f, 2);
ImGui.TableSetupColumn("calls", ImGuiTableColumnFlags.WidthStretch, 0.10f, 3);
ImGui.TableSetupColumn("avg", ImGuiTableColumnFlags.WidthStretch, 0.10f, 4);
ImGui.TableSetupColumn("p95", ImGuiTableColumnFlags.WidthStretch, 0.10f, 5);
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthStretch, 0.32f, 0);
ImGui.TableSetupColumn("ms", ImGuiTableColumnFlags.WidthStretch, 0.11f, 1);
ImGui.TableSetupColumn("self", ImGuiTableColumnFlags.WidthStretch, 0.11f, 2);
ImGui.TableSetupColumn("calls", ImGuiTableColumnFlags.WidthStretch, 0.08f, 3);
ImGui.TableSetupColumn("avg", ImGuiTableColumnFlags.WidthStretch, 0.09f, 4);
ImGui.TableSetupColumn("p95", ImGuiTableColumnFlags.WidthStretch, 0.09f, 5);
ImGui.TableSetupColumn("alloc(B)", ImGuiTableColumnFlags.WidthStretch, 0.10f, 6);
ImGui.TableSetupColumn("self alloc", ImGuiTableColumnFlags.WidthStretch, 0.10f, 7);
ImGui.TableSetupScrollFreeze(0, 1); // Make row always visible
ImGui.TableHeadersRow();
foreach (KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms)> combinedData in orderedCombinedData)
foreach (KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms, long allocBytes, long selfAllocBytes)> combinedData in orderedCombinedData)
{
ImGui.TableNextRow();
ImGui.TableNextColumn();
@@ -237,6 +245,10 @@ namespace Nerfed.Editor.Systems
ImGui.Text($"{combinedData.Value.avgMs:0.000}");
ImGui.TableNextColumn();
ImGui.Text($"{combinedData.Value.p95Ms:0.000}");
ImGui.TableNextColumn();
ImGui.Text($"{combinedData.Value.allocBytes}");
ImGui.TableNextColumn();
ImGui.Text($"{combinedData.Value.selfAllocBytes}");
}
ImGui.EndTable();
@@ -245,10 +257,10 @@ namespace Nerfed.Editor.Systems
ImGui.EndChild();
}
private static IOrderedEnumerable<KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms)>> CalculateCombinedData(Profiler.Frame frame)
private static IOrderedEnumerable<KeyValuePair<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms, long allocBytes, long selfAllocBytes)>> CalculateCombinedData(Profiler.Frame frame)
{
IReadOnlyDictionary<string, Profiler.RollingLabelMetrics> rollingData = Profiler.GetRollingLabelMetricsSnapshot();
Dictionary<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms)> combinedRecordData = new Dictionary<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms)>(128);
Dictionary<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms, long allocBytes, long selfAllocBytes)> combinedRecordData = new Dictionary<string, (double ms, double selfMs, uint calls, double avgMs, double p95Ms, long allocBytes, long selfAllocBytes)>(128);
foreach (KeyValuePair<string, Profiler.LabelMetrics> metric in frame.LabelMetrics)
{
Profiler.RollingLabelMetrics rolling = default;
@@ -257,7 +269,7 @@ namespace Nerfed.Editor.Systems
rolling = found;
}
combinedRecordData[metric.Key] = (metric.Value.InclusiveMs, metric.Value.SelfMs, metric.Value.Calls, rolling.AverageMs, rolling.P95Ms);
combinedRecordData[metric.Key] = (metric.Value.InclusiveMs, metric.Value.SelfMs, metric.Value.Calls, rolling.AverageMs, rolling.P95Ms, metric.Value.AllocatedBytes, metric.Value.SelfAllocatedBytes);
}
return combinedRecordData.OrderByDescending(x => x.Value.ms);
}