private List <ICallStatisticsTreeNode> GetThreadCallTreeNodes(ThreadStatisticsData thread) { var result = new List <ICallStatisticsTreeNode>(); var childNode = CreateCallTreeNode(thread.CallTreeRoot, null); if (childNode != null) { result.Add(childNode); } return(result); }
private void UpdateCallTree(ThreadStatisticsData threadData, Sample sample) { var call = threadData.CallTreeRoot; call.SamplesInclusive += sample.Samples; call.TimeInclusive += sample.Time; call.AllocatedMemoryInclusive += sample.AllocatedMemory; var x = sample.StackItems; if (x.Count <= 1) { call.SamplesExclusive += sample.Samples; call.TimeExclusive += sample.Time; call.AllocatedMemoryExclusive += sample.AllocatedMemory; } for (int i = x.Count - 2; i >= 0; i--) { var si = x[i]; var child = call.FindChildById(si.FunctionIntId); if (child == null) { var function = PDataContainer.GetFunction(si.FunctionIntId); child = new FunctionCall(si.FunctionIntId, function.Name, function.Signature) { Parent = call, }; call.Children.Add(child); threadData.FunctionCalls.Add(child); } child.SamplesInclusive += sample.Samples; child.TimeInclusive += sample.Time; child.AllocatedMemoryInclusive += sample.AllocatedMemory; if (i == 0) { child.SamplesExclusive += sample.Samples; child.TimeExclusive += sample.Time; child.AllocatedMemoryExclusive += sample.AllocatedMemory; } call = child; } }
private List <IHotPath> BuildThreadHotPaths(ThreadStatisticsData thread, StatisticsType statisticsType, IProfilingStatisticsTotals totals, double hotPathThreshold) { var maxValue = totals.GetValue(statisticsType); return(thread.FunctionCalls .Where(call => call.SamplesInclusive > 0 && ((100.0 * FunctionCallValue(call, statisticsType) / maxValue) >= hotPathThreshold)) .OrderByDescending(call => FunctionCallValue(call, statisticsType)) .Select <FunctionCall, IHotPath>(call => new HotPath { Name = call.Name, Children = CallPath(call), AllocatedMemoryExclusive = call.AllocatedMemoryExclusive, SamplesExclusive = call.SamplesExclusive, TimeExclusive = call.TimeExclusive, }) .ToList()); }
private IThreadStatisticsRaw BuildThreadStatisticsRaw(ThreadStatisticsData thread) { var totals = new ProfilingStatisticsTotals( new Dictionary <StatisticsType, ulong>() { { StatisticsType.Sample, thread.SamplesTotal }, { StatisticsType.Memory, thread.MemoryTotal }, { StatisticsType.Time, thread.TimeTotal } }); return(new ThreadStatisticsRaw { Totals = totals, Methods = thread.Methods.Values.ToList(), Lines = thread.Lines.Values.ToList(), CallTree = GetThreadCallTreeNodes(thread), CpuUtilization = ApplicationCpuUtilization.Count == 0 ? ApplicationCpuUtilization : thread.CpuUtilization }); }
public void BuildStatisticsRaw(ISelectedTimeFrame timeFrame) { ApplicationStatistics = new ApplicationStatistics(); ThreadsStatisticsRaw = new Dictionary <ulong, IThreadStatisticsRaw>(); _applicationData = new StatisticsData(); foreach (var thread in _sessionThreads.Values) { if (thread.InternalId == Thread.FakeThreadId) { continue; } var threadStatistics = new ThreadStatisticsData { CpuUtilization = thread.CpuUtilization }; foreach (var s in PDataContainer.Samples[thread.InternalId]) { if (s.TimeMilliseconds >= timeFrame.Start) { if (s.TimeMilliseconds > timeFrame.End) { break; } ProcessSample(threadStatistics, s); } } ThreadsStatisticsRaw.Add(thread.InternalId, BuildThreadStatisticsRaw(threadStatistics)); } ApplicationStatistics = BuildApplicationStatistics(); }
private IThreadStatistics BuildThreadStatistics(ThreadStatisticsData thread) { var totals = new ProfilingStatisticsTotals( new Dictionary <StatisticsType, ulong>() { { StatisticsType.Sample, thread.SamplesTotal }, { StatisticsType.Memory, thread.MemoryTotal }, { StatisticsType.Time, thread.TimeTotal } }); var threadMethods = thread.Methods.Values; var methods = new Dictionary <StatisticsType, List <IMethodStatistics> > { { StatisticsType.Memory, threadMethods.Where(method => method.AllocatedMemoryExclusive > 0) .OrderByDescending(method => method.AllocatedMemoryExclusive) .ToList() }, { StatisticsType.Sample, threadMethods.Where(method => method.SamplesExclusive > 0) .OrderByDescending(method => method.SamplesExclusive) .ToList() }, { StatisticsType.Time, threadMethods.Where(method => method.TimeExclusive > 0) .OrderByDescending(method => method.TimeExclusive) .ToList() } }; var hotPaths = new Dictionary <StatisticsType, List <IHotPath> > { { StatisticsType.Memory, BuildThreadHotPaths(thread, StatisticsType.Memory, totals, HotPathThreshold) }, { StatisticsType.Sample, BuildThreadHotPaths(thread, StatisticsType.Sample, totals, HotPathThreshold) }, { StatisticsType.Time, BuildThreadHotPaths(thread, StatisticsType.Time, totals, HotPathThreshold) } }; var callTree = GetThreadCallTreeNodes(thread); var threadLines = thread.Lines.Values; var lines = new Dictionary <StatisticsType, List <ISourceLineStatistics> > { { StatisticsType.Memory, threadLines.Where(line => line.AllocatedMemoryInclusive > 0) .OrderByDescending(line => line.AllocatedMemoryInclusive) .ToList() }, { StatisticsType.Sample, threadLines.Where(line => line.SamplesInclusive > 0) .OrderByDescending(line => line.SamplesInclusive) .ToList() }, { StatisticsType.Time, threadLines.Where(line => line.TimeInclusive > 0) .OrderByDescending(line => line.TimeInclusive) .ToList() } }; return(new ThreadStatistics { Totals = totals, Methods = methods, CallTree = callTree, HotPaths = hotPaths, Lines = lines, CpuUtilization = ApplicationCpuUtilization.Count == 0 ? ApplicationCpuUtilization : thread.CpuUtilization }); }
private void ProcessSample(ThreadStatisticsData threadData, Sample sample) { UpdateStatisticsData(threadData, sample); UpdateStatisticsData(_applicationData, sample); UpdateCallTree(threadData, sample); }