diff --git a/src/AddIns/Misc/Profiler/Controller/Data/CallTreeNode.cs b/src/AddIns/Misc/Profiler/Controller/Data/CallTreeNode.cs
index e343114d6e..1c36a3bf2f 100644
--- a/src/AddIns/Misc/Profiler/Controller/Data/CallTreeNode.cs
+++ b/src/AddIns/Misc/Profiler/Controller/Data/CallTreeNode.cs
@@ -66,10 +66,24 @@ namespace ICSharpCode.Profiler.Controller.Data
public abstract bool IsActiveAtStart { get; }
///
- /// Gets how many CPU cycles where spent inside this method, including sub calls.
+ /// Gets how many CPU cycles were spent inside this method, including sub calls.
///
public abstract long CpuCyclesSpent { get; }
+ ///
+ /// Gets how many CPU cycles were spent inside this method, excluding sub calls.
+ ///
+ public virtual long CpuCyclesSpentSelf {
+ get {
+ return GetCpuCyclesSelf();
+ }
+ }
+
+ long GetCpuCyclesSelf()
+ {
+ return CpuCyclesSpent - Children.Aggregate(0L, (sum, item) => sum + item.CpuCyclesSpent);
+ }
+
///
/// Gets the name of the method including namespace and class name.
///
diff --git a/src/AddIns/Misc/Profiler/Controller/Data/PerformanceCounterDescriptor.cs b/src/AddIns/Misc/Profiler/Controller/Data/PerformanceCounterDescriptor.cs
index a0994088d6..fa24e2f3fb 100644
--- a/src/AddIns/Misc/Profiler/Controller/Data/PerformanceCounterDescriptor.cs
+++ b/src/AddIns/Misc/Profiler/Controller/Data/PerformanceCounterDescriptor.cs
@@ -11,8 +11,6 @@ namespace ICSharpCode.Profiler.Controller.Data
{
public class PerformanceCounterDescriptor
{
-
-
public PerformanceCounterDescriptor()
{
}
diff --git a/src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs b/src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs
index faa088f191..742a1ce07f 100644
--- a/src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs
+++ b/src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs
@@ -350,7 +350,7 @@ namespace ICSharpCode.Profiler.Controller.Data
///
public override IQueryable GetFunctions(int startIndex, int endIndex)
{
- if (startIndex < 0 || startIndex > endIndex)
+ if (startIndex < 0 || startIndex >= this.dataSets.Count)
throw new ArgumentOutOfRangeException("startIndex", startIndex, "Value must be between 0 and " + endIndex);
if (endIndex < startIndex || endIndex >= this.DataSets.Count)
throw new ArgumentOutOfRangeException("endIndex", endIndex, "Value must be between " + startIndex + " and " + (this.DataSets.Count - 1));
diff --git a/src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs b/src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs
index 2a58f1c37d..357083d872 100644
--- a/src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs
+++ b/src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs
@@ -25,67 +25,75 @@ namespace ICSharpCode.Profiler.Controller.Data
this.unitTests = new List(unitTests);
}
- ///
- /// Gets a reference to the name, return type and parameter list of the method.
- ///
+ ///
public override NameMapping NameMapping {
get {
return new NameMapping(0, null, "Merged node", null);
}
}
+ ///
public override long CpuCyclesSpent {
get {
return 0;
}
}
+ ///
public override bool IsActiveAtStart {
get {
return this.unitTests.Any(test => test.IsActiveAtStart);
}
}
+ ///
public override double TimeSpent {
get {
return 0;
}
}
-
+
+ ///
public override int RawCallCount {
get {
return 0;
}
}
-
+
+ ///
public override CallTreeNode Parent {
get {
return null;
}
}
-
+
+ ///
public override CallTreeNode Merge(System.Collections.Generic.IEnumerable nodes)
{
// throw new ShouldNeverHappenException();
throw new NotSupportedException("Cannot merge a UnitTestRootCallTreeNode (should never be possible)");
}
-
+
+ ///
public override int GetHashCode()
{
return this.unitTests.Aggregate(0, (sum, item) => sum ^= item.GetHashCode());
}
-
+
+ ///
public override bool Equals(CallTreeNode other)
{
return (other is UnitTestRootCallTreeNode) && (other as UnitTestRootCallTreeNode).unitTests.SequenceEqual(unitTests);
}
-
+
+ ///
public override IQueryable Callers {
get {
return Enumerable.Empty().AsQueryable();
}
}
-
+
+ ///
public override IQueryable Children {
get {
return unitTests.AsQueryable();
diff --git a/src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml b/src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml
index 5d083796cd..584d149085 100644
--- a/src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml
+++ b/src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml
@@ -40,7 +40,7 @@
-
+
diff --git a/src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs b/src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs
index 16b2a4a503..e7a5acc2ad 100644
--- a/src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs
+++ b/src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs
@@ -46,7 +46,7 @@ namespace ICSharpCode.Profiler.Controls
public event EventHandler> RequestBringIntoView;
protected virtual void OnRequestBringIntoView(NodeEventArgs e)
- {
+ {
if (RequestBringIntoView != null) {
RequestBringIntoView(this, e);
}
@@ -101,6 +101,15 @@ namespace ICSharpCode.Profiler.Controls
}
}
+ public Visibility HotPathIndicatorVisibility {
+ get {
+ if (TimePercentageOfParent >= 0.2)
+ return Visibility.Visible;
+
+ return Visibility.Collapsed;
+ }
+ }
+
CallTreeNodeViewModel GetNodeFromLevel(int level)
{
if (this.level > level) {
@@ -258,7 +267,7 @@ namespace ICSharpCode.Profiler.Controls
OnPropertyChanged("IsExpanded");
this.IsExpandedChanged(new NodeEventArgs(this));
- if (!isExpanded) {
+ if (isExpanded) {
DeselectChildren(children);
}
}
@@ -328,6 +337,35 @@ namespace ICSharpCode.Profiler.Controls
}
}
+ public string TimeSpentSelf {
+ get {
+ if (!node.IsThread) {
+ double value = node.TimeSpent - node.Children.Aggregate(0.0, (sum, item) => sum + item.TimeSpent);
+ return value.ToString("f6") + "ms";
+ } else
+ return null;
+ }
+ }
+
+ public string TimeSpentSelfPerCall {
+ get {
+ if (!node.IsThread) {
+ double value = node.TimeSpent - node.Children.Aggregate(0.0, (sum, item) => sum + item.TimeSpent);
+ return (value / node.CallCount).ToString("f6") + "ms";
+ } else
+ return null;
+ }
+ }
+
+ public string TimeSpentPerCall {
+ get {
+ if (!node.IsThread)
+ return (node.TimeSpent / node.CallCount).ToString("f6") + "ms";
+ else
+ return null;
+ }
+ }
+
public string CallCount {
get {
if (!node.IsThread)
diff --git a/src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj b/src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj
index 75f5ba6ae5..6b72e24eb7 100644
--- a/src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj
+++ b/src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj
@@ -93,6 +93,8 @@
+
+
{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}
Controller
diff --git a/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml b/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml
index adc437ca03..de3977ef6d 100644
--- a/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml
+++ b/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml
@@ -77,6 +77,7 @@
+
@@ -97,6 +98,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs b/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs
index d64425c792..8db95da07c 100644
--- a/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs
+++ b/src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs
@@ -86,8 +86,6 @@ namespace ICSharpCode.Profiler.Controls
ad.Child = bar;
layer.Add(ad);
- CallTreeNode resultRoot;
-
searchTask.Execute(
() => DoSearchInBackground(list.Roots.Select(i => i.Node).ToList(), start, end, text, true),
result => SearchCompleted(result, layer, ad),
@@ -160,9 +158,12 @@ namespace ICSharpCode.Profiler.Controls
this.treeView.SizeChanged += delegate(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0 &&
(nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) > 0) {
- if ((nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) >=
- (e.NewSize.Width - this.callCountColumn.Width - this.percentColumn.Width - this.timeSpentColumn.Width))
- this.nameColumn.Width = e.NewSize.Width - this.callCountColumn.Width - this.percentColumn.Width - this.timeSpentColumn.Width - 25;
+ double newValue = e.NewSize.Width - this.callCountColumn.Width
+ - this.percentColumn.Width - this.timeSpentColumn.Width
+ - this.timeSpentSelfColumn.Width - this.timeSpentPerCallColumn.Width
+ - this.timeSpentSelfPerCallColumn.Width;
+ if ((nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) >= newValue)
+ this.nameColumn.Width = newValue - 25;
else
nameColumn.Width += (e.NewSize.Width - e.PreviousSize.Width);
}