diff --git a/VContainer/Assets/VContainer/Editor/Diagnostics/VContainerDiagnosticsTreeView.cs b/VContainer/Assets/VContainer/Editor/Diagnostics/VContainerDiagnosticsTreeView.cs index a710c5af..f72a3083 100644 --- a/VContainer/Assets/VContainer/Editor/Diagnostics/VContainerDiagnosticsTreeView.cs +++ b/VContainer/Assets/VContainer/Editor/Diagnostics/VContainerDiagnosticsTreeView.cs @@ -17,6 +17,7 @@ public sealed class DiagnosticsInfoTreeViewItem : TreeViewItem public RegistrationBuilder RegistrationBuilder => DiagnosticsInfo.RegisterInfo.RegistrationBuilder; public Registration Registration => DiagnosticsInfo.ResolveInfo.Registration; public int? RefCount => DiagnosticsInfo.ResolveInfo.RefCount; + public long ResolveTime => DiagnosticsInfo.ResolveInfo.ResolveTime; public string TypeSummary => TypeNameHelper.GetTypeAlias(Registration.ImplementationType); @@ -85,6 +86,7 @@ public sealed class VContainerDiagnosticsInfoTreeView : TreeView new MultiColumnHeaderState.Column { headerContent = new GUIContent("Register"), width = 15f }, new MultiColumnHeaderState.Column { headerContent = new GUIContent("RefCount"), width = 5f }, new MultiColumnHeaderState.Column { headerContent = new GUIContent("Scope"), width = 20f }, + new MultiColumnHeaderState.Column { headerContent = new GUIContent("Time"), width = 20f }, }; static int idSeed; @@ -246,6 +248,9 @@ protected override void RowGUI(RowGUIArgs args) case 5: EditorGUI.LabelField(cellRect, item.ScopeName, labelStyle); break; + case 6: + EditorGUI.LabelField(cellRect, item.ResolveTime.ToString(), labelStyle); + break; default: throw new ArgumentOutOfRangeException(nameof(columnIndex), columnIndex, null); } @@ -295,6 +300,10 @@ IEnumerable Sort( return ascending ? items.OrderBy(x => x.ScopeName) : items.OrderByDescending(x => x.ScopeName); + case 6: + return ascending + ? items.OrderBy(x => x.ResolveTime) + : items.OrderByDescending(x => x.ResolveTime); default: throw new ArgumentOutOfRangeException(nameof(sortedColumnIndex), sortedColumnIndex, null); } diff --git a/VContainer/Assets/VContainer/Runtime/Diagnostics/DiagnosticsCollector.cs b/VContainer/Assets/VContainer/Runtime/Diagnostics/DiagnosticsCollector.cs index 546c4742..89c8abc2 100644 --- a/VContainer/Assets/VContainer/Runtime/Diagnostics/DiagnosticsCollector.cs +++ b/VContainer/Assets/VContainer/Runtime/Diagnostics/DiagnosticsCollector.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading; using VContainer.Internal; @@ -69,9 +70,13 @@ public object TraceResolve(Registration registration, Func owner?.Dependencies.Add(current); resolveCallStack.Value.Push(current); + var watch = Stopwatch.StartNew(); var instance = resolving(registration); + watch.Stop(); resolveCallStack.Value.Pop(); + SetResolveTime(current, watch.ElapsedMilliseconds); + if (!current.ResolveInfo.Instances.Contains(instance)) { current.ResolveInfo.Instances.Add(instance); @@ -82,6 +87,28 @@ public object TraceResolve(Registration registration, Func return resolving(registration); } + private static void SetResolveTime(DiagnosticsInfo current, long elapsedMilliseconds) + { + var resolves = current.ResolveInfo.RefCount; + var resolveTime = current.ResolveInfo.ResolveTime; + + switch (current.ResolveInfo.Registration.Lifetime) + { + case Lifetime.Transient: + resolveTime = (resolveTime * (resolves - 1) + elapsedMilliseconds) / resolves; + break; + case Lifetime.Scoped: + case Lifetime.Singleton: + if (elapsedMilliseconds > resolveTime) + resolveTime = elapsedMilliseconds; + break; + default: + throw new ArgumentOutOfRangeException(); + } + + current.ResolveInfo.ResolveTime = resolveTime; + } + public void NotifyContainerBuilt(IObjectResolver container) => DiagnositcsContext.NotifyContainerBuilt(container); } diff --git a/VContainer/Assets/VContainer/Runtime/Diagnostics/ResolveInfo.cs b/VContainer/Assets/VContainer/Runtime/Diagnostics/ResolveInfo.cs index 1d337cf3..2047b76a 100644 --- a/VContainer/Assets/VContainer/Runtime/Diagnostics/ResolveInfo.cs +++ b/VContainer/Assets/VContainer/Runtime/Diagnostics/ResolveInfo.cs @@ -8,6 +8,7 @@ public sealed class ResolveInfo public List Instances { get; } = new List(); public int MaxDepth { get; set; } = -1; public int RefCount { get; set; } + public long ResolveTime { get; set; } public ResolveInfo(Registration registration) {