Skip to content

Commit 1e2a9a7

Browse files
authored
Perfetto plugin - Memory optimizations and table renaming (#48)
Made some memory optimizations to help improve the sluggishness in WPA when viewing large traces. Memory optimizations reduce memory usage by about 50%. UI is more responsive now. Optimizations include Used string interning on the high-count string fields Switched the variable length argument fields from List to string[] Changed bunch of longs to ints. These are mostly ID fields. Confirmed they are int or smaller within Perfetto Table renaming Removed redundant "Perfetto" from all tables and column config names Added column configs that graph by StartTime instead of duration for GenericEvents Added fix for duplicate GUIDs
1 parent 99032fe commit 1e2a9a7

38 files changed

Lines changed: 227 additions & 159 deletions

LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/Cloud-init/Tables/Metadata/FileStatsMetadataTable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace CloudInitMPTAddin.Tables.Metadata
1515
public sealed class FileStatsMetadataTable
1616
{
1717
public static readonly TableDescriptor TableDescriptor = new TableDescriptor(
18-
Guid.Parse("{40AF86E5-0DF8-47B1-9A01-1D6C3529B75B}"),
18+
Guid.Parse("{806a2599-97a2-4ff7-9ed8-9ac891edeef6}"),
1919
"File Stats",
2020
"Statistics for text files",
2121
isMetadataTable: true,

LinuxLogParsers/LinuxPlugins-MicrosoftPerformanceToolkSDK/WaLinuxAgent/Tables/Metadata/FileStatsMetadataTable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace WaLinuxAgentMPTAddin.Tables.Metadata
3131
public static class FileStatsMetadataTable
3232
{
3333
public static readonly TableDescriptor TableDescriptor = new TableDescriptor(
34-
Guid.Parse("{40AF86E5-0DF8-47B1-9A01-1D6C3529B75B}"),
34+
Guid.Parse("{10a8a80a-27a3-42b8-8cde-3a374080e01e}"),
3535
"File Stats",
3636
"Statistics for text files",
3737
isMetadataTable: true,

PerfettoCds/Pipeline/CompositeDataCookers/PerfettoFtraceEventCooker.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using PerfettoCds.Pipeline.DataOutput;
1111
using PerfettoCds.Pipeline.SourceDataCookers;
1212
using PerfettoProcessor;
13+
using Utilities;
1314

1415
namespace PerfettoCds.Pipeline.CompositeDataCookers
1516
{
@@ -78,23 +79,23 @@ join arg in argsData on raw.ArgSetId equals arg.ArgSetId into args
7879
// Each event has multiple of these arguments. They get stored in lists
7980
foreach (var arg in result.args)
8081
{
81-
argKeys.Add(arg.ArgKey);
82+
argKeys.Add(Common.StringIntern(arg.ArgKey));
8283
switch (arg.ValueType)
8384
{
8485
case "json":
8586
case "string":
86-
values.Add(arg.StringValue);
87+
values.Add(Common.StringIntern(arg.StringValue));
8788
break;
8889
case "bool":
8990
case "int":
90-
values.Add(arg.IntValue.ToString());
91+
values.Add(Common.StringIntern(arg.IntValue.ToString()));
9192
break;
9293
case "uint":
9394
case "pointer":
94-
values.Add(((uint)arg.IntValue).ToString());
95+
values.Add(Common.StringIntern(((uint)arg.IntValue).ToString()));
9596
break;
9697
case "real":
97-
values.Add(arg.RealValue.ToString());
98+
values.Add(Common.StringIntern(arg.RealValue.ToString()));
9899
break;
99100
default:
100101
throw new Exception("Unexpected Perfetto value type");

PerfettoCds/Pipeline/CompositeDataCookers/PerfettoGenericEventCooker.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using PerfettoCds.Pipeline.DataOutput;
1616
using PerfettoCds.Pipeline.SourceDataCookers;
1717
using PerfettoProcessor;
18+
using Utilities;
1819

1920
namespace PerfettoCds.Pipeline.CompositeDataCookers
2021
{
@@ -188,12 +189,12 @@ join processTrack in processTrackData on slice.TrackId equals processTrack.Id in
188189
// Each event has multiple of these "debug annotations". They get stored in lists
189190
foreach (var arg in result.args)
190191
{
191-
argKeys.Add(arg.ArgKey);
192+
argKeys.Add(Common.StringIntern(arg.ArgKey));
192193
switch (arg.ValueType)
193194
{
194195
case "json":
195196
case "string":
196-
values.Add(arg.StringValue);
197+
values.Add(Common.StringIntern(arg.StringValue));
197198

198199
// Check if there are mappings present and if the arg key is the keyword we're looking for
199200
if (ProviderGuidMapping.Count > 0 && arg.ArgKey.ToLower().Contains(ProviderDebugAnnotationKey))
@@ -210,14 +211,14 @@ join processTrack in processTrackData on slice.TrackId equals processTrack.Id in
210211
break;
211212
case "bool":
212213
case "int":
213-
values.Add(arg.IntValue.ToString());
214+
values.Add(Common.StringIntern(arg.IntValue.ToString()));
214215
break;
215216
case "uint":
216217
case "pointer":
217-
values.Add(((uint)arg.IntValue).ToString());
218+
values.Add(Common.StringIntern(((uint)arg.IntValue).ToString()));
218219
break;
219220
case "real":
220-
values.Add(arg.RealValue.ToString());
221+
values.Add(Common.StringIntern(arg.RealValue.ToString()));
221222
break;
222223
default:
223224
throw new Exception("Unexpected Perfetto value type");
@@ -282,7 +283,6 @@ join processTrack in processTrackData on slice.TrackId equals processTrack.Id in
282283
new Timestamp(result.slice.RelativeTimestamp + result.slice.Duration) :
283284
longestEndTs,
284285
result.slice.Category,
285-
result.slice.ArgSetId,
286286
values,
287287
argKeys,
288288
processName,

PerfettoCds/Pipeline/DataOutput/PerfettoCpuCountersEvent.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace PerfettoCds.Pipeline.DataOutput
88
public readonly struct PerfettoCpuCountersEvent
99
{
1010
// The specific CPU core
11-
public long CpuNum { get; }
11+
public int CpuNum { get; }
1212
public Timestamp StartTimestamp { get; }
1313
public TimestampDelta Duration { get; }
1414

@@ -36,7 +36,7 @@ public readonly struct PerfettoCpuCountersEvent
3636
/// <summary>
3737
/// For populating the current counter values
3838
/// </summary>
39-
public PerfettoCpuCountersEvent(long cpuNum, Timestamp startTimestamp, TimestampDelta duration,
39+
public PerfettoCpuCountersEvent(int cpuNum, Timestamp startTimestamp, TimestampDelta duration,
4040
double userNs,
4141
double userNiceNs,
4242
double systemModeNs,
@@ -70,7 +70,7 @@ public PerfettoCpuCountersEvent(long cpuNum, Timestamp startTimestamp, Timestamp
7070
/// <summary>
7171
/// When we have a previous event to compare to, we can calculate the percent change
7272
/// </summary>
73-
public PerfettoCpuCountersEvent(long cpuNum, Timestamp startTimestamp, TimestampDelta duration,
73+
public PerfettoCpuCountersEvent(int cpuNum, Timestamp startTimestamp, TimestampDelta duration,
7474
double userNs,
7575
double userNiceNs,
7676
double systemModeNs,

PerfettoCds/Pipeline/DataOutput/PerfettoCpuFrequencyEvent.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ public readonly struct PerfettoCpuFrequencyEvent
1313
// The current frequency of this CPU
1414
public double CpuFrequency { get; }
1515
// The specific CPU core
16-
public long CpuNum { get; }
16+
public int CpuNum { get; }
1717
public Timestamp StartTimestamp { get; }
1818
// Type of CPU frequency event. Whether it's an idle change or frequency change event
1919
public string Name { get; }
2020
public TimestampDelta Duration { get; }
2121
public bool IsIdle { get; }
2222

23-
public PerfettoCpuFrequencyEvent(double cpuFrequency, long cpuNum, Timestamp startTimestamp, TimestampDelta duration, string name, bool isIdle)
23+
public PerfettoCpuFrequencyEvent(double cpuFrequency, int cpuNum, Timestamp startTimestamp, TimestampDelta duration, string name, bool isIdle)
2424
{
2525
this.CpuFrequency = cpuFrequency;
2626
this.CpuNum = cpuNum;

PerfettoCds/Pipeline/DataOutput/PerfettoCpuSchedEvent.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33
using Microsoft.Performance.SDK;
4+
using Utilities;
45

56
namespace PerfettoCds.Pipeline.DataOutput
67
{
@@ -14,21 +15,21 @@ public readonly struct PerfettoCpuSchedEvent
1415
public TimestampDelta Duration { get; }
1516
public Timestamp StartTimestamp { get; }
1617
public Timestamp EndTimestamp { get; }
17-
public long Cpu { get; }
18+
public int Cpu { get; }
1819
public string EndState { get; }
19-
public long Priority { get; }
20+
public int Priority { get; }
2021

2122
public PerfettoCpuSchedEvent(string processName,
2223
string threadName,
2324
TimestampDelta duration,
2425
Timestamp startTimestamp,
2526
Timestamp endTimestamp,
26-
long cpu,
27+
int cpu,
2728
string endState,
28-
long priority)
29+
int priority)
2930
{
30-
this.ProcessName = processName;
31-
this.ThreadName = threadName;
31+
this.ProcessName = Common.StringIntern(processName);
32+
this.ThreadName = Common.StringIntern(threadName);
3233
this.Duration = duration;
3334
this.StartTimestamp = startTimestamp;
3435
this.EndTimestamp = endTimestamp;

PerfettoCds/Pipeline/DataOutput/PerfettoFtraceEvent.cs.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33
using Microsoft.Performance.SDK;
44
using System.Collections.Generic;
5+
using Utilities;
56

67
namespace PerfettoCds.Pipeline.DataOutput
78
{
@@ -13,29 +14,29 @@ public readonly struct PerfettoFtraceEvent
1314
public Timestamp StartTimestamp { get; }
1415
public string ProcessName { get; }
1516
public string ThreadName { get; }
16-
public long Cpu { get; }
17+
public int Cpu { get; }
1718
// Name of the ftrace event
1819
public string Name { get; }
1920

2021
// From Args table. Variable number per event
21-
public List<string> Values { get; }
22-
public List<string> ArgKeys { get; }
22+
public string[] Values { get; }
23+
public string[] ArgKeys { get; }
2324

2425
public PerfettoFtraceEvent(Timestamp startTimestamp,
2526
string processName,
2627
string threadName,
27-
long cpu,
28+
int cpu,
2829
string name,
2930
List<string> values,
3031
List<string> argKeys)
3132
{
3233
this.StartTimestamp = startTimestamp;
33-
this.ProcessName = processName;
34-
this.ThreadName = threadName;
34+
this.ProcessName = Common.StringIntern(processName);
35+
this.ThreadName = Common.StringIntern(threadName);
3536
this.Cpu = cpu;
36-
this.Name = name;
37-
this.Values = values;
38-
this.ArgKeys = argKeys;
37+
this.Name = Common.StringIntern(name);
38+
this.Values = values.ToArray();
39+
this.ArgKeys = argKeys.ToArray();
3940
}
4041
}
4142
}

PerfettoCds/Pipeline/DataOutput/PerfettoGenericEvent.cs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.Performance.SDK;
44
using PerfettoProcessor;
55
using System.Collections.Generic;
6+
using Utilities;
67

78
namespace PerfettoCds.Pipeline.DataOutput
89
{
@@ -20,12 +21,9 @@ public readonly struct PerfettoGenericEvent
2021
public Timestamp EndTimestamp { get; }
2122
public string Category { get; }
2223

23-
// Key between slice and args table
24-
public long ArgSetId { get; }
25-
2624
// From Args table. The debug annotations for an event. Variable number per event
27-
public List<string> Values { get; }
28-
public List<string> ArgKeys { get; }
25+
public string[] Values { get; }
26+
public string[] ArgKeys { get; }
2927

3028
// From Process table
3129
public string Process { get; }
@@ -35,7 +33,7 @@ public readonly struct PerfettoGenericEvent
3533

3634
public string Provider { get; }
3735

38-
public long? ParentId{ get; }
36+
public int? ParentId{ get; }
3937

4038
public int ParentTreeDepthLevel { get; }
4139

@@ -49,29 +47,27 @@ public PerfettoGenericEvent(string eventName,
4947
Timestamp startTimestamp,
5048
Timestamp endTimestamp,
5149
string category,
52-
long argSetId,
5350
List<string> values,
5451
List<string> argKeys,
5552
string process,
5653
string thread,
5754
string provider,
5855
PerfettoThreadTrackEvent threadTrack,
59-
long? parentId,
56+
int? parentId,
6057
int parentTreeDepthLevel,
6158
string[] parentEventNameTree)
6259
{
63-
EventName = eventName;
64-
Type = type;
60+
EventName = Common.StringIntern(eventName);
61+
Type = Common.StringIntern(type);
6562
Duration = duration;
6663
StartTimestamp = startTimestamp;
6764
EndTimestamp = endTimestamp;
68-
Category = category;
69-
ArgSetId = argSetId;
70-
Values = values;
71-
ArgKeys = argKeys;
72-
Process = process;
73-
Thread = thread;
74-
Provider = provider;
65+
Category = Common.StringIntern(category);
66+
Values = values.ToArray();
67+
ArgKeys = argKeys.ToArray();
68+
Process = Common.StringIntern(process);
69+
Thread = Common.StringIntern(thread);
70+
Provider = Common.StringIntern(provider);
7571
ThreadTrack = threadTrack;
7672
ParentId = parentId;
7773
ParentTreeDepthLevel = parentTreeDepthLevel;

PerfettoCds/Pipeline/DataOutput/PerfettoLogcatEvent.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33
using Microsoft.Performance.SDK;
44
using System.Collections.Generic;
5+
using Utilities;
56

67
namespace PerfettoCds.Pipeline.DataOutput
78
{
@@ -25,11 +26,11 @@ public PerfettoLogcatEvent(Timestamp startTimestamp,
2526
string message)
2627
{
2728
this.StartTimestamp = startTimestamp;
28-
this.ProcessName = processName;
29-
this.ThreadName = threadName;
30-
this.Priority = priority;
31-
this.Tag = tag;
32-
this.Message = message;
29+
this.ProcessName = Common.StringIntern(processName);
30+
this.ThreadName = Common.StringIntern(threadName);
31+
this.Priority = Common.StringIntern(priority);
32+
this.Tag = Common.StringIntern(tag);
33+
this.Message = Common.StringIntern(message);
3334
}
3435
}
3536
}

0 commit comments

Comments
 (0)