From 22828b187514ff9fc64768148f7ee61051b70fa2 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 17:59:25 +0100 Subject: [PATCH 1/3] 3.4 imptovement - show executed 0 ms nodes as 1ms --- TuneUp/ProfiledNodeViewModel.cs | 47 +++++++++++---------------------- TuneUp/TuneUpWindowViewModel.cs | 41 +++++++++++----------------- 2 files changed, 31 insertions(+), 57 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index e6f06d2..b60c355 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -71,7 +71,6 @@ internal set private const string DefaultGroupName = "Title "; private const string DefaultDisplayGroupName = "Title"; - private string name = String.Empty; /// /// The name of this profiled node. This value can be either an actual /// node name or can be virtually any row you want to append to @@ -98,7 +97,8 @@ public string Name } internal set { name = value; } } - + private string name = String.Empty; + /// /// The order number of this node in the most recent graph run. /// Returns null if the node was not executed during the most recent graph run. @@ -130,47 +130,32 @@ public int? GroupExecutionOrderNumber private int? groupExecutionOrderNumber; /// - /// The most recent execution time of this node + /// The most recent execution time of this node in milliseconds /// - public TimeSpan ExecutionTime + public int ExecutionMilliseconds { - get => executionTime; + get => executionMilliseconds; set { - executionTime = value; - RaisePropertyChanged(nameof(ExecutionTime)); + executionMilliseconds = value; RaisePropertyChanged(nameof(ExecutionMilliseconds)); } } - private TimeSpan executionTime; - - /// - /// The total execution time of all node in the group. - /// - public TimeSpan GroupExecutionTime - { - get => groupExecutionTime; - set - { - groupExecutionTime = value; - RaisePropertyChanged(nameof(GroupExecutionTime)); - } - } - private TimeSpan groupExecutionTime; + private int executionMilliseconds; /// - /// The most recent execution time of this node in milliseconds + /// The total execution time of the group in milliseconds /// - public int ExecutionMilliseconds + public int GroupExecutionMilliseconds { - get => executionMilliseconds; + get => groupExecutionMilliseconds; set { - executionMilliseconds = value; - RaisePropertyChanged(nameof(ExecutionMilliseconds)); + groupExecutionMilliseconds = value; + RaisePropertyChanged(nameof(GroupExecutionMilliseconds)); } } - private int executionMilliseconds; + private int groupExecutionMilliseconds; /// /// Indicates whether this node was executed on the most recent graph run @@ -245,7 +230,6 @@ public bool ShowGroupIndicator } private bool showGroupIndicator; - /// /// The background brush for this node /// If this node represents a group, it inherits the background color from the associated AnnotationModel @@ -333,7 +317,7 @@ internal void ResetGroupProperties() GroupGUID = Guid.Empty; GroupName = string.Empty; GroupExecutionOrderNumber = null; - GroupExecutionTime = TimeSpan.Zero; + GroupExecutionMilliseconds = 0; } internal void ApplyGroupProperties(ProfiledNodeViewModel profiledGroup) @@ -361,10 +345,9 @@ public ProfiledNodeViewModel(NodeModel node) /// row display name /// execution time in ms /// state which determine grouping - public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState state) + public ProfiledNodeViewModel(string name, ProfiledNodeState state) { this.Name = name; - this.ExecutionTime = exTimeSum; State = state; } diff --git a/TuneUp/TuneUpWindowViewModel.cs b/TuneUp/TuneUpWindowViewModel.cs index 81c7716..afac08a 100644 --- a/TuneUp/TuneUpWindowViewModel.cs +++ b/TuneUp/TuneUpWindowViewModel.cs @@ -540,10 +540,9 @@ private void CalculateGroupNodes() ProfiledNodeViewModel groupTotalTimeNode = null; bool groupIsRenamed = false; - // Reset group state + // Reset group state and execution time profiledGroup.State = profiledNode.State; - profiledGroup.GroupExecutionTime = TimeSpan.Zero; // Reset execution time - profiledGroup.ExecutionMilliseconds = 0; // Reset UI execution time + profiledGroup.GroupExecutionMilliseconds = 0; MoveNodeToCollection(profiledGroup, ProfiledNodesLatestRun); // Ensure the profiledGroup is in latest run // Check if the group has been renamed @@ -565,8 +564,7 @@ private void CalculateGroupNodes() else if (processedNodes.Add(node)) { // Update group state, execution order, and execution time - profiledGroup.GroupExecutionTime += node.ExecutionTime; // accurate, for sorting - profiledGroup.ExecutionMilliseconds += node.ExecutionMilliseconds; // rounded, for display in UI + profiledGroup.GroupExecutionMilliseconds += node.ExecutionMilliseconds; node.GroupExecutionOrderNumber = groupExecutionCounter; node.ShowGroupIndicator = ShowGroups; if (groupIsRenamed) @@ -578,7 +576,6 @@ private void CalculateGroupNodes() // Update the properties of the group node profiledGroup.GroupExecutionOrderNumber = groupExecutionCounter++; - profiledGroup.ExecutionTime = profiledGroup.GroupExecutionTime; profiledGroup.WasExecutedOnLastRun = true; @@ -591,7 +588,7 @@ private void CalculateGroupNodes() // Update the groupExecutionTime for all nodes of the group for the purposes of sorting foreach (var node in nodesInGroup) { - node.GroupExecutionTime = profiledGroup.GroupExecutionTime; + node.GroupExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds; } } } @@ -601,7 +598,7 @@ private void CalculateGroupNodes() !profiledNode.IsGroupExecutionTime) { profiledNode.GroupExecutionOrderNumber = groupExecutionCounter++; - profiledNode.GroupExecutionTime = profiledNode.ExecutionTime; + profiledNode.GroupExecutionMilliseconds = profiledNode.ExecutionMilliseconds; } } @@ -628,11 +625,11 @@ internal void OnNodeExecutionEnd(NodeModel nm) var executionTime = profiledNode.Stopwatch.Elapsed; if (executionTime > TimeSpan.Zero) - { - profiledNode.ExecutionTime = executionTime; + { // Assign execution time and manually set the execution milliseconds value // so that group node execution time is based on rounded millisecond values. - profiledNode.ExecutionMilliseconds = (int)Math.Round(executionTime.TotalMilliseconds); + // Nodes should display at least 1ms execution time if they are executed. + profiledNode.ExecutionMilliseconds = Math.Max(1, (int)Math.Round(executionTime.TotalMilliseconds)); if (!profiledNode.WasExecutedOnLastRun) { @@ -737,22 +734,17 @@ internal void OnGroupPropertyChanged(object sender, PropertyChangedEventArgs e) groupDictionary[groupModel.GUID].Add(profiledNode); } - // Update group execution time + // Update group execution times var totalExecutionMilliseconds = existingProfiledNodesInGroup .Where(n => !n.IsGroupExecutionTime) .Sum(n => n.ExecutionMilliseconds); - var totalExecutionTime = existingProfiledNodesInGroup - .Where(n => !n.IsGroupExecutionTime) - .Select(n => n.ExecutionTime) - .Aggregate(TimeSpan.Zero, (sum, next) => sum + next); - profiledGroup.ExecutionMilliseconds = totalExecutionMilliseconds; - profiledGroup.GroupExecutionTime = totalExecutionTime; + profiledGroup.ExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds = totalExecutionMilliseconds; // update the grouped nodes foreach (var profiledNode in existingProfiledNodesInGroup) { - profiledNode.GroupExecutionTime = totalExecutionTime; + profiledNode.GroupExecutionMilliseconds = totalExecutionMilliseconds; if (profiledNode.IsGroupExecutionTime) { profiledNode.ExecutionMilliseconds = totalExecutionMilliseconds; @@ -893,7 +885,7 @@ private void OnCurrentWorkspaceCleared(IWorkspaceModel workspace) private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel profiledGroup) { var groupTotalTimeNode = new ProfiledNodeViewModel( - ProfiledNodeViewModel.GroupExecutionTimeString, TimeSpan.Zero, ProfiledNodeState.NotExecuted) + ProfiledNodeViewModel.GroupExecutionTimeString, ProfiledNodeState.NotExecuted) { GroupGUID = profiledGroup.GroupGUID, GroupName = profiledGroup.GroupName, @@ -912,8 +904,7 @@ private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel pro private void UpdateGroupTotalTimeNodeProperties(ProfiledNodeViewModel groupTotalTimeNode, ProfiledNodeViewModel profiledGroup) { groupTotalTimeNode.State = profiledGroup.State; - groupTotalTimeNode.GroupExecutionTime = profiledGroup.GroupExecutionTime; // Accurate, for sorting - groupTotalTimeNode.ExecutionMilliseconds = profiledGroup.ExecutionMilliseconds; // Rounded, for display in UI + groupTotalTimeNode.GroupExecutionMilliseconds = groupTotalTimeNode.ExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds; groupTotalTimeNode.GroupExecutionOrderNumber = profiledGroup.GroupExecutionOrderNumber; groupTotalTimeNode.WasExecutedOnLastRun = true; @@ -1034,15 +1025,15 @@ public void ApplyCustomSorting(CollectionViewSource collection, string explicitS case SortByTime: if (showGroups) { - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupExecutionTime), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupExecutionMilliseconds), sortDirection)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupGUID), sortDirection)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.IsGroup), ListSortDirection.Descending)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.IsGroupExecutionTime), ListSortDirection.Ascending)); - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionTime), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionMilliseconds), sortDirection)); } else { - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionTime), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionMilliseconds), sortDirection)); } break; case SortByName: From aa5fc7b4efa172441f31594807f5a306f3df9c57 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Thu, 3 Oct 2024 06:23:04 +0100 Subject: [PATCH 2/3] Revert "3.4 imptovement - show executed 0 ms nodes as 1ms" This reverts commit 22828b187514ff9fc64768148f7ee61051b70fa2. --- TuneUp/ProfiledNodeViewModel.cs | 47 ++++++++++++++++++++++----------- TuneUp/TuneUpWindowViewModel.cs | 41 +++++++++++++++++----------- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index b60c355..e6f06d2 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -71,6 +71,7 @@ internal set private const string DefaultGroupName = "Title "; private const string DefaultDisplayGroupName = "Title"; + private string name = String.Empty; /// /// The name of this profiled node. This value can be either an actual /// node name or can be virtually any row you want to append to @@ -97,8 +98,7 @@ public string Name } internal set { name = value; } } - private string name = String.Empty; - + /// /// The order number of this node in the most recent graph run. /// Returns null if the node was not executed during the most recent graph run. @@ -130,32 +130,47 @@ public int? GroupExecutionOrderNumber private int? groupExecutionOrderNumber; /// - /// The most recent execution time of this node in milliseconds + /// The most recent execution time of this node /// - public int ExecutionMilliseconds + public TimeSpan ExecutionTime { - get => executionMilliseconds; + get => executionTime; set { - executionMilliseconds = value; + executionTime = value; + RaisePropertyChanged(nameof(ExecutionTime)); RaisePropertyChanged(nameof(ExecutionMilliseconds)); } } - private int executionMilliseconds; + private TimeSpan executionTime; /// - /// The total execution time of the group in milliseconds + /// The total execution time of all node in the group. /// - public int GroupExecutionMilliseconds + public TimeSpan GroupExecutionTime { - get => groupExecutionMilliseconds; + get => groupExecutionTime; set { - groupExecutionMilliseconds = value; - RaisePropertyChanged(nameof(GroupExecutionMilliseconds)); + groupExecutionTime = value; + RaisePropertyChanged(nameof(GroupExecutionTime)); } } - private int groupExecutionMilliseconds; + private TimeSpan groupExecutionTime; + + /// + /// The most recent execution time of this node in milliseconds + /// + public int ExecutionMilliseconds + { + get => executionMilliseconds; + set + { + executionMilliseconds = value; + RaisePropertyChanged(nameof(ExecutionMilliseconds)); + } + } + private int executionMilliseconds; /// /// Indicates whether this node was executed on the most recent graph run @@ -230,6 +245,7 @@ public bool ShowGroupIndicator } private bool showGroupIndicator; + /// /// The background brush for this node /// If this node represents a group, it inherits the background color from the associated AnnotationModel @@ -317,7 +333,7 @@ internal void ResetGroupProperties() GroupGUID = Guid.Empty; GroupName = string.Empty; GroupExecutionOrderNumber = null; - GroupExecutionMilliseconds = 0; + GroupExecutionTime = TimeSpan.Zero; } internal void ApplyGroupProperties(ProfiledNodeViewModel profiledGroup) @@ -345,9 +361,10 @@ public ProfiledNodeViewModel(NodeModel node) /// row display name /// execution time in ms /// state which determine grouping - public ProfiledNodeViewModel(string name, ProfiledNodeState state) + public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState state) { this.Name = name; + this.ExecutionTime = exTimeSum; State = state; } diff --git a/TuneUp/TuneUpWindowViewModel.cs b/TuneUp/TuneUpWindowViewModel.cs index afac08a..81c7716 100644 --- a/TuneUp/TuneUpWindowViewModel.cs +++ b/TuneUp/TuneUpWindowViewModel.cs @@ -540,9 +540,10 @@ private void CalculateGroupNodes() ProfiledNodeViewModel groupTotalTimeNode = null; bool groupIsRenamed = false; - // Reset group state and execution time + // Reset group state profiledGroup.State = profiledNode.State; - profiledGroup.GroupExecutionMilliseconds = 0; + profiledGroup.GroupExecutionTime = TimeSpan.Zero; // Reset execution time + profiledGroup.ExecutionMilliseconds = 0; // Reset UI execution time MoveNodeToCollection(profiledGroup, ProfiledNodesLatestRun); // Ensure the profiledGroup is in latest run // Check if the group has been renamed @@ -564,7 +565,8 @@ private void CalculateGroupNodes() else if (processedNodes.Add(node)) { // Update group state, execution order, and execution time - profiledGroup.GroupExecutionMilliseconds += node.ExecutionMilliseconds; + profiledGroup.GroupExecutionTime += node.ExecutionTime; // accurate, for sorting + profiledGroup.ExecutionMilliseconds += node.ExecutionMilliseconds; // rounded, for display in UI node.GroupExecutionOrderNumber = groupExecutionCounter; node.ShowGroupIndicator = ShowGroups; if (groupIsRenamed) @@ -576,6 +578,7 @@ private void CalculateGroupNodes() // Update the properties of the group node profiledGroup.GroupExecutionOrderNumber = groupExecutionCounter++; + profiledGroup.ExecutionTime = profiledGroup.GroupExecutionTime; profiledGroup.WasExecutedOnLastRun = true; @@ -588,7 +591,7 @@ private void CalculateGroupNodes() // Update the groupExecutionTime for all nodes of the group for the purposes of sorting foreach (var node in nodesInGroup) { - node.GroupExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds; + node.GroupExecutionTime = profiledGroup.GroupExecutionTime; } } } @@ -598,7 +601,7 @@ private void CalculateGroupNodes() !profiledNode.IsGroupExecutionTime) { profiledNode.GroupExecutionOrderNumber = groupExecutionCounter++; - profiledNode.GroupExecutionMilliseconds = profiledNode.ExecutionMilliseconds; + profiledNode.GroupExecutionTime = profiledNode.ExecutionTime; } } @@ -625,11 +628,11 @@ internal void OnNodeExecutionEnd(NodeModel nm) var executionTime = profiledNode.Stopwatch.Elapsed; if (executionTime > TimeSpan.Zero) - { + { + profiledNode.ExecutionTime = executionTime; // Assign execution time and manually set the execution milliseconds value // so that group node execution time is based on rounded millisecond values. - // Nodes should display at least 1ms execution time if they are executed. - profiledNode.ExecutionMilliseconds = Math.Max(1, (int)Math.Round(executionTime.TotalMilliseconds)); + profiledNode.ExecutionMilliseconds = (int)Math.Round(executionTime.TotalMilliseconds); if (!profiledNode.WasExecutedOnLastRun) { @@ -734,17 +737,22 @@ internal void OnGroupPropertyChanged(object sender, PropertyChangedEventArgs e) groupDictionary[groupModel.GUID].Add(profiledNode); } - // Update group execution times + // Update group execution time var totalExecutionMilliseconds = existingProfiledNodesInGroup .Where(n => !n.IsGroupExecutionTime) .Sum(n => n.ExecutionMilliseconds); + var totalExecutionTime = existingProfiledNodesInGroup + .Where(n => !n.IsGroupExecutionTime) + .Select(n => n.ExecutionTime) + .Aggregate(TimeSpan.Zero, (sum, next) => sum + next); - profiledGroup.ExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds = totalExecutionMilliseconds; + profiledGroup.ExecutionMilliseconds = totalExecutionMilliseconds; + profiledGroup.GroupExecutionTime = totalExecutionTime; // update the grouped nodes foreach (var profiledNode in existingProfiledNodesInGroup) { - profiledNode.GroupExecutionMilliseconds = totalExecutionMilliseconds; + profiledNode.GroupExecutionTime = totalExecutionTime; if (profiledNode.IsGroupExecutionTime) { profiledNode.ExecutionMilliseconds = totalExecutionMilliseconds; @@ -885,7 +893,7 @@ private void OnCurrentWorkspaceCleared(IWorkspaceModel workspace) private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel profiledGroup) { var groupTotalTimeNode = new ProfiledNodeViewModel( - ProfiledNodeViewModel.GroupExecutionTimeString, ProfiledNodeState.NotExecuted) + ProfiledNodeViewModel.GroupExecutionTimeString, TimeSpan.Zero, ProfiledNodeState.NotExecuted) { GroupGUID = profiledGroup.GroupGUID, GroupName = profiledGroup.GroupName, @@ -904,7 +912,8 @@ private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel pro private void UpdateGroupTotalTimeNodeProperties(ProfiledNodeViewModel groupTotalTimeNode, ProfiledNodeViewModel profiledGroup) { groupTotalTimeNode.State = profiledGroup.State; - groupTotalTimeNode.GroupExecutionMilliseconds = groupTotalTimeNode.ExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds; + groupTotalTimeNode.GroupExecutionTime = profiledGroup.GroupExecutionTime; // Accurate, for sorting + groupTotalTimeNode.ExecutionMilliseconds = profiledGroup.ExecutionMilliseconds; // Rounded, for display in UI groupTotalTimeNode.GroupExecutionOrderNumber = profiledGroup.GroupExecutionOrderNumber; groupTotalTimeNode.WasExecutedOnLastRun = true; @@ -1025,15 +1034,15 @@ public void ApplyCustomSorting(CollectionViewSource collection, string explicitS case SortByTime: if (showGroups) { - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupExecutionMilliseconds), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupExecutionTime), sortDirection)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupGUID), sortDirection)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.IsGroup), ListSortDirection.Descending)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.IsGroupExecutionTime), ListSortDirection.Ascending)); - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionMilliseconds), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionTime), sortDirection)); } else { - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionMilliseconds), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionTime), sortDirection)); } break; case SortByName: From c2a6ee69f6f8bd5f3226367142c7ac948e9d19f9 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Thu, 3 Oct 2024 07:01:27 +0100 Subject: [PATCH 3/3] public props back --- TuneUp/ProfiledNodeViewModel.cs | 21 ++++++++++++++----- TuneUp/TuneUpWindowViewModel.cs | 37 +++++++++++++-------------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index e6f06d2..09a9252 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -172,6 +172,20 @@ public int ExecutionMilliseconds } private int executionMilliseconds; + /// + /// The total execution time of this group in milliseconds + /// + public int GroupExecutionMilliseconds + { + get => groupExecutionMilliseconds; + set + { + groupExecutionMilliseconds = value; + RaisePropertyChanged(nameof(GroupExecutionMilliseconds)); + } + } + private int groupExecutionMilliseconds; + /// /// Indicates whether this node was executed on the most recent graph run /// @@ -245,7 +259,6 @@ public bool ShowGroupIndicator } private bool showGroupIndicator; - /// /// The background brush for this node /// If this node represents a group, it inherits the background color from the associated AnnotationModel @@ -333,7 +346,7 @@ internal void ResetGroupProperties() GroupGUID = Guid.Empty; GroupName = string.Empty; GroupExecutionOrderNumber = null; - GroupExecutionTime = TimeSpan.Zero; + GroupExecutionMilliseconds = 0; } internal void ApplyGroupProperties(ProfiledNodeViewModel profiledGroup) @@ -359,12 +372,10 @@ public ProfiledNodeViewModel(NodeModel node) /// An alternative constructor which we can customize data for display in TuneUp datagrid /// /// row display name - /// execution time in ms /// state which determine grouping - public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState state) + public ProfiledNodeViewModel(string name, ProfiledNodeState state) { this.Name = name; - this.ExecutionTime = exTimeSum; State = state; } diff --git a/TuneUp/TuneUpWindowViewModel.cs b/TuneUp/TuneUpWindowViewModel.cs index 81c7716..5487878 100644 --- a/TuneUp/TuneUpWindowViewModel.cs +++ b/TuneUp/TuneUpWindowViewModel.cs @@ -540,10 +540,9 @@ private void CalculateGroupNodes() ProfiledNodeViewModel groupTotalTimeNode = null; bool groupIsRenamed = false; - // Reset group state + // Reset group state and execution time profiledGroup.State = profiledNode.State; - profiledGroup.GroupExecutionTime = TimeSpan.Zero; // Reset execution time - profiledGroup.ExecutionMilliseconds = 0; // Reset UI execution time + profiledNode.GroupExecutionMilliseconds = 0; MoveNodeToCollection(profiledGroup, ProfiledNodesLatestRun); // Ensure the profiledGroup is in latest run // Check if the group has been renamed @@ -565,8 +564,7 @@ private void CalculateGroupNodes() else if (processedNodes.Add(node)) { // Update group state, execution order, and execution time - profiledGroup.GroupExecutionTime += node.ExecutionTime; // accurate, for sorting - profiledGroup.ExecutionMilliseconds += node.ExecutionMilliseconds; // rounded, for display in UI + profiledGroup.GroupExecutionMilliseconds += node.ExecutionMilliseconds; node.GroupExecutionOrderNumber = groupExecutionCounter; node.ShowGroupIndicator = ShowGroups; if (groupIsRenamed) @@ -578,7 +576,6 @@ private void CalculateGroupNodes() // Update the properties of the group node profiledGroup.GroupExecutionOrderNumber = groupExecutionCounter++; - profiledGroup.ExecutionTime = profiledGroup.GroupExecutionTime; profiledGroup.WasExecutedOnLastRun = true; @@ -591,7 +588,7 @@ private void CalculateGroupNodes() // Update the groupExecutionTime for all nodes of the group for the purposes of sorting foreach (var node in nodesInGroup) { - node.GroupExecutionTime = profiledGroup.GroupExecutionTime; + node.GroupExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds; } } } @@ -601,7 +598,7 @@ private void CalculateGroupNodes() !profiledNode.IsGroupExecutionTime) { profiledNode.GroupExecutionOrderNumber = groupExecutionCounter++; - profiledNode.GroupExecutionTime = profiledNode.ExecutionTime; + profiledNode.GroupExecutionMilliseconds = profiledNode.ExecutionMilliseconds; } } @@ -629,10 +626,10 @@ internal void OnNodeExecutionEnd(NodeModel nm) if (executionTime > TimeSpan.Zero) { - profiledNode.ExecutionTime = executionTime; // Assign execution time and manually set the execution milliseconds value // so that group node execution time is based on rounded millisecond values. - profiledNode.ExecutionMilliseconds = (int)Math.Round(executionTime.TotalMilliseconds); + // Nodes should display at least 1ms execution time if they are executed. + profiledNode.ExecutionMilliseconds = Math.Max(1, (int)Math.Round(executionTime.TotalMilliseconds)); if (!profiledNode.WasExecutedOnLastRun) { @@ -741,18 +738,13 @@ internal void OnGroupPropertyChanged(object sender, PropertyChangedEventArgs e) var totalExecutionMilliseconds = existingProfiledNodesInGroup .Where(n => !n.IsGroupExecutionTime) .Sum(n => n.ExecutionMilliseconds); - var totalExecutionTime = existingProfiledNodesInGroup - .Where(n => !n.IsGroupExecutionTime) - .Select(n => n.ExecutionTime) - .Aggregate(TimeSpan.Zero, (sum, next) => sum + next); - profiledGroup.ExecutionMilliseconds = totalExecutionMilliseconds; - profiledGroup.GroupExecutionTime = totalExecutionTime; + profiledGroup.ExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds = totalExecutionMilliseconds; // update the grouped nodes foreach (var profiledNode in existingProfiledNodesInGroup) { - profiledNode.GroupExecutionTime = totalExecutionTime; + profiledNode.GroupExecutionMilliseconds = totalExecutionMilliseconds; if (profiledNode.IsGroupExecutionTime) { profiledNode.ExecutionMilliseconds = totalExecutionMilliseconds; @@ -893,7 +885,7 @@ private void OnCurrentWorkspaceCleared(IWorkspaceModel workspace) private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel profiledGroup) { var groupTotalTimeNode = new ProfiledNodeViewModel( - ProfiledNodeViewModel.GroupExecutionTimeString, TimeSpan.Zero, ProfiledNodeState.NotExecuted) + ProfiledNodeViewModel.GroupExecutionTimeString, ProfiledNodeState.NotExecuted) { GroupGUID = profiledGroup.GroupGUID, GroupName = profiledGroup.GroupName, @@ -912,8 +904,7 @@ private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel pro private void UpdateGroupTotalTimeNodeProperties(ProfiledNodeViewModel groupTotalTimeNode, ProfiledNodeViewModel profiledGroup) { groupTotalTimeNode.State = profiledGroup.State; - groupTotalTimeNode.GroupExecutionTime = profiledGroup.GroupExecutionTime; // Accurate, for sorting - groupTotalTimeNode.ExecutionMilliseconds = profiledGroup.ExecutionMilliseconds; // Rounded, for display in UI + groupTotalTimeNode.GroupExecutionMilliseconds = groupTotalTimeNode.ExecutionMilliseconds = profiledGroup.GroupExecutionMilliseconds; groupTotalTimeNode.GroupExecutionOrderNumber = profiledGroup.GroupExecutionOrderNumber; groupTotalTimeNode.WasExecutedOnLastRun = true; @@ -1034,15 +1025,15 @@ public void ApplyCustomSorting(CollectionViewSource collection, string explicitS case SortByTime: if (showGroups) { - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupExecutionTime), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupExecutionMilliseconds), sortDirection)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.GroupGUID), sortDirection)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.IsGroup), ListSortDirection.Descending)); collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.IsGroupExecutionTime), ListSortDirection.Ascending)); - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionTime), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionMilliseconds), sortDirection)); } else { - collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionTime), sortDirection)); + collection.SortDescriptions.Add(new SortDescription(nameof(ProfiledNodeViewModel.ExecutionMilliseconds), sortDirection)); } break; case SortByName: