mirror of
https://github.com/Kae7in/perfview
synced 2026-08-09 12:09:44 +00:00
Speed up CTF process name parsing
Cache result of process name parsing to not constantly rebuild the string.
This commit is contained in:
@@ -37,6 +37,7 @@ namespace Microsoft.Diagnostics.Tracing.Ctf
|
|||||||
private CtfMetadata _metadata;
|
private CtfMetadata _metadata;
|
||||||
private CtfStream _streamDefinition;
|
private CtfStream _streamDefinition;
|
||||||
CtfEventHeader _header = new CtfEventHeader();
|
CtfEventHeader _header = new CtfEventHeader();
|
||||||
|
public Dictionary<int, string> _processes = new Dictionary<int, string>();
|
||||||
|
|
||||||
private bool _eof;
|
private bool _eof;
|
||||||
private GCHandle _handle;
|
private GCHandle _handle;
|
||||||
@@ -148,20 +149,25 @@ namespace Microsoft.Diagnostics.Tracing.Ctf
|
|||||||
result = ReadStruct(eventContext);
|
result = ReadStruct(eventContext);
|
||||||
_header.Pid = eventContext.GetFieldValue<int>(result, "_vpid");
|
_header.Pid = eventContext.GetFieldValue<int>(result, "_vpid");
|
||||||
_header.Tid = eventContext.GetFieldValue<int>(result, "_vtid");
|
_header.Tid = eventContext.GetFieldValue<int>(result, "_vtid");
|
||||||
|
|
||||||
int procnameIndex = eventContext.GetFieldIndex("_procname");
|
if (IsProcessStartEvent(evt) || !_processes.TryGetValue(_header.Pid, out _header.ProcessName))
|
||||||
object[] procname = (object[])(result[procnameIndex]);
|
|
||||||
processName.Clear();
|
|
||||||
for (int i = 0; i < 17; i++)
|
|
||||||
{
|
{
|
||||||
sbyte b = (sbyte)procname[i];
|
int procnameIndex = eventContext.GetFieldIndex("_procname");
|
||||||
if (b == 0)
|
object[] procname = (object[])(result[procnameIndex]);
|
||||||
break;
|
processName.Clear();
|
||||||
|
for (int i = 0; i < 17; i++)
|
||||||
|
{
|
||||||
|
sbyte b = (sbyte)procname[i];
|
||||||
|
if (b == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
processName.Append((char)b);
|
processName.Append((char)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
string name = processName.ToString();
|
||||||
|
_header.ProcessName = name;
|
||||||
|
_processes[_header.Pid] = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
_header.ProcessName = processName.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_readHeader = true;
|
_readHeader = true;
|
||||||
@@ -169,6 +175,11 @@ namespace Microsoft.Diagnostics.Tracing.Ctf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsProcessStartEvent(CtfEvent evt)
|
||||||
|
{
|
||||||
|
return evt.Name == "sched_process_exec";
|
||||||
|
}
|
||||||
|
|
||||||
public void ResetBuffer()
|
public void ResetBuffer()
|
||||||
{
|
{
|
||||||
_bitOffset = 0;
|
_bitOffset = 0;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace Microsoft.Diagnostics.Tracing
|
|||||||
private List<Tuple<ZipArchiveEntry, CtfMetadata>> _channels;
|
private List<Tuple<ZipArchiveEntry, CtfMetadata>> _channels;
|
||||||
private TraceEventNativeMethods.EVENT_RECORD* _header;
|
private TraceEventNativeMethods.EVENT_RECORD* _header;
|
||||||
private Dictionary<string, ETWMapping> _eventMapping;
|
private Dictionary<string, ETWMapping> _eventMapping;
|
||||||
|
private Dictionary<int, string> _processes = new Dictionary<int, string>();
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private StreamWriter _debugOut;
|
private StreamWriter _debugOut;
|
||||||
@@ -482,6 +483,7 @@ namespace Microsoft.Diagnostics.Tracing
|
|||||||
CtfEventHeader header = entry.Current;
|
CtfEventHeader header = entry.Current;
|
||||||
CtfEvent evt = header.Event;
|
CtfEvent evt = header.Event;
|
||||||
lastTimestamp = header.Timestamp;
|
lastTimestamp = header.Timestamp;
|
||||||
|
_processes[header.Pid] = header.ProcessName;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (_debugOut != null)
|
if (_debugOut != null)
|
||||||
@@ -549,6 +551,15 @@ namespace Microsoft.Diagnostics.Tracing
|
|||||||
return _header;
|
return _header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal override string ProcessName(int processID, long timeQPC)
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
if (!_processes.TryGetValue(processID, out name))
|
||||||
|
name = $"Process({processID.ToString("x")})";
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
private ETWMapping GetTraceEvent(CtfEvent evt)
|
private ETWMapping GetTraceEvent(CtfEvent evt)
|
||||||
{
|
{
|
||||||
ETWMapping result;
|
ETWMapping result;
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ namespace Microsoft.Diagnostics.Tracing.Parsers
|
|||||||
{
|
{
|
||||||
private Action<SchedulerProcessTraceData> _action;
|
private Action<SchedulerProcessTraceData> _action;
|
||||||
private static string[] _payloadNames;
|
private static string[] _payloadNames;
|
||||||
|
|
||||||
|
|
||||||
|
public int Tid { get { throw new NotImplementedException(); } }
|
||||||
|
|
||||||
public SchedulerProcessTraceData(Action<SchedulerProcessTraceData> action, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName)
|
public SchedulerProcessTraceData(Action<SchedulerProcessTraceData> action, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName)
|
||||||
: base(eventID, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName)
|
: base(eventID, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName)
|
||||||
@@ -124,7 +127,7 @@ namespace Microsoft.Diagnostics.Tracing.Parsers
|
|||||||
{
|
{
|
||||||
Prefix(sb);
|
Prefix(sb);
|
||||||
XmlAttrib(sb, "ProcessID", ProcessID);
|
XmlAttrib(sb, "ProcessID", ProcessID);
|
||||||
XmlAttrib(sb, "ImageFileName", ImageFileName);
|
XmlAttrib(sb, "ProcessName", ProcessName);
|
||||||
sb.Append("/>");
|
sb.Append("/>");
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user