Speed up CTF process name parsing

Cache result of process name parsing to not constantly rebuild the
string.
This commit is contained in:
Lee Culver
2016-05-27 16:02:42 -07:00
parent 78ed82e698
commit 57c58646f8
3 changed files with 37 additions and 12 deletions
+22 -11
View File
@@ -37,6 +37,7 @@ namespace Microsoft.Diagnostics.Tracing.Ctf
private CtfMetadata _metadata;
private CtfStream _streamDefinition;
CtfEventHeader _header = new CtfEventHeader();
public Dictionary<int, string> _processes = new Dictionary<int, string>();
private bool _eof;
private GCHandle _handle;
@@ -148,20 +149,25 @@ namespace Microsoft.Diagnostics.Tracing.Ctf
result = ReadStruct(eventContext);
_header.Pid = eventContext.GetFieldValue<int>(result, "_vpid");
_header.Tid = eventContext.GetFieldValue<int>(result, "_vtid");
int procnameIndex = eventContext.GetFieldIndex("_procname");
object[] procname = (object[])(result[procnameIndex]);
processName.Clear();
for (int i = 0; i < 17; i++)
if (IsProcessStartEvent(evt) || !_processes.TryGetValue(_header.Pid, out _header.ProcessName))
{
sbyte b = (sbyte)procname[i];
if (b == 0)
break;
int procnameIndex = eventContext.GetFieldIndex("_procname");
object[] procname = (object[])(result[procnameIndex]);
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;
@@ -169,6 +175,11 @@ namespace Microsoft.Diagnostics.Tracing.Ctf
}
}
private static bool IsProcessStartEvent(CtfEvent evt)
{
return evt.Name == "sched_process_exec";
}
public void ResetBuffer()
{
_bitOffset = 0;
+11
View File
@@ -36,6 +36,7 @@ namespace Microsoft.Diagnostics.Tracing
private List<Tuple<ZipArchiveEntry, CtfMetadata>> _channels;
private TraceEventNativeMethods.EVENT_RECORD* _header;
private Dictionary<string, ETWMapping> _eventMapping;
private Dictionary<int, string> _processes = new Dictionary<int, string>();
#if DEBUG
private StreamWriter _debugOut;
@@ -482,6 +483,7 @@ namespace Microsoft.Diagnostics.Tracing
CtfEventHeader header = entry.Current;
CtfEvent evt = header.Event;
lastTimestamp = header.Timestamp;
_processes[header.Pid] = header.ProcessName;
#if DEBUG
if (_debugOut != null)
@@ -549,6 +551,15 @@ namespace Microsoft.Diagnostics.Tracing
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)
{
ETWMapping result;
@@ -71,6 +71,9 @@ namespace Microsoft.Diagnostics.Tracing.Parsers
{
private Action<SchedulerProcessTraceData> _action;
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)
: base(eventID, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName)
@@ -124,7 +127,7 @@ namespace Microsoft.Diagnostics.Tracing.Parsers
{
Prefix(sb);
XmlAttrib(sb, "ProcessID", ProcessID);
XmlAttrib(sb, "ImageFileName", ImageFileName);
XmlAttrib(sb, "ProcessName", ProcessName);
sb.Append("/>");
return sb;
}