feat: Indenting stopwatch results into a tree format

This commit is contained in:
Chris Cameron
2018-10-08 14:54:16 -04:00
parent 8a260e0475
commit e01e41c449

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using ICD.Common.Properties; using ICD.Common.Properties;
using ICD.Common.Utils.Extensions; using ICD.Common.Utils.Extensions;
#if SIMPLSHARP #if SIMPLSHARP
@@ -18,6 +19,8 @@ namespace ICD.Common.Utils.Timers
private readonly Stopwatch m_Stopwatch; private readonly Stopwatch m_Stopwatch;
private static int s_ProfileIndentCount;
#region Properties #region Properties
public long ElapsedTicks { get { return m_Stopwatch.ElapsedTicks; } } public long ElapsedTicks { get { return m_Stopwatch.ElapsedTicks; } }
@@ -104,9 +107,18 @@ namespace ICD.Common.Utils.Timers
if (action == null) if (action == null)
throw new ArgumentNullException("action"); throw new ArgumentNullException("action");
IcdStopwatch stopwatch = StartNew(); s_ProfileIndentCount++;
action();
PrintProfile(stopwatch.ElapsedTicks, name); try
{
IcdStopwatch stopwatch = StartNew();
action();
PrintProfile(stopwatch.ElapsedTicks, name);
}
finally
{
s_ProfileIndentCount--;
}
} }
/// <summary> /// <summary>
@@ -122,11 +134,20 @@ namespace ICD.Common.Utils.Timers
if (func == null) if (func == null)
throw new ArgumentNullException("func"); throw new ArgumentNullException("func");
IcdStopwatch stopwatch = StartNew(); s_ProfileIndentCount++;
T output = func();
PrintProfile(stopwatch.ElapsedTicks, name);
return output; try
{
IcdStopwatch stopwatch = StartNew();
T output = func();
PrintProfile(stopwatch.ElapsedTicks, name);
return output;
}
finally
{
s_ProfileIndentCount--;
}
} }
/// <summary> /// <summary>
@@ -192,12 +213,16 @@ namespace ICD.Common.Utils.Timers
// TODO - Print a fancy table with a total duration for the sequence // TODO - Print a fancy table with a total duration for the sequence
List<T> output = new List<T>();
using (IEnumerator<T> enumerator = enumerable.GetEnumerator()) using (IEnumerator<T> enumerator = enumerable.GetEnumerator())
{ {
// ReSharper disable once AccessToDisposedClosure // ReSharper disable once AccessToDisposedClosure
while (Profile(() => enumerator.MoveNext(), name)) while (Profile(() => enumerator.MoveNext(), name))
yield return enumerator.Current; output.Add(enumerator.Current);
} }
return output;
} }
/// <summary> /// <summary>
@@ -208,20 +233,27 @@ namespace ICD.Common.Utils.Timers
/// <param name="name"></param> /// <param name="name"></param>
public static void Profile(EventHandler eventHandler, object sender, string name) public static void Profile(EventHandler eventHandler, object sender, string name)
{ {
if (eventHandler == null) s_ProfileIndentCount++;
try
{ {
PrintProfile(0, string.Format("{0} - No invocations", name)); if (eventHandler == null)
return; {
PrintProfile(0, string.Format("{0} - No invocations", name));
return;
}
}
finally
{
s_ProfileIndentCount--;
} }
// TODO - Print a fancy table with a total duration for the event // TODO - Print a fancy table with a total duration for the event
// ReSharper disable PossibleInvalidCastExceptionInForeachLoop foreach (EventHandler subscriber in eventHandler.GetInvocationList().Cast<EventHandler>())
foreach (EventHandler subscriber in eventHandler.GetInvocationList())
// ReSharper restore PossibleInvalidCastExceptionInForeachLoop
{ {
string subscriberName = string.Format("{0} - {1}.{2}", name, subscriber.Target.GetType().Name, string subscriberName = string.Format("{0} - {1}.{2}", name, subscriber.Target.GetType().Name,
subscriber.GetMethodInfo().GetSignature(true)); subscriber.GetMethodInfo().GetSignature(true));
EventHandler subscriber1 = subscriber; EventHandler subscriber1 = subscriber;
Profile(() => subscriber1(sender, EventArgs.Empty), subscriberName); Profile(() => subscriber1(sender, EventArgs.Empty), subscriberName);
@@ -239,20 +271,27 @@ namespace ICD.Common.Utils.Timers
public static void Profile<T>(EventHandler<T> eventHandler, object sender, T eventArgs, string name) public static void Profile<T>(EventHandler<T> eventHandler, object sender, T eventArgs, string name)
where T : EventArgs where T : EventArgs
{ {
if (eventHandler == null) s_ProfileIndentCount++;
try
{ {
PrintProfile(0, string.Format("{0} - No invocations", name)); if (eventHandler == null)
return; {
PrintProfile(0, string.Format("{0} - No invocations", name));
return;
}
}
finally
{
s_ProfileIndentCount--;
} }
// TODO - Print a fancy table with a total duration for the event // TODO - Print a fancy table with a total duration for the event
// ReSharper disable PossibleInvalidCastExceptionInForeachLoop foreach (EventHandler<T> subscriber in eventHandler.GetInvocationList().Cast<EventHandler<T>>())
foreach (EventHandler<T> subscriber in eventHandler.GetInvocationList())
// ReSharper restore PossibleInvalidCastExceptionInForeachLoop
{ {
string subscriberName = string.Format("{0} - {1}.{2}", name, subscriber.Target.GetType().Name, string subscriberName = string.Format("{0} - {1}.{2}", name, subscriber.Target.GetType().Name,
subscriber.GetMethodInfo().GetSignature(true)); subscriber.GetMethodInfo().GetSignature(true));
EventHandler<T> subscriber1 = subscriber; EventHandler<T> subscriber1 = subscriber;
Profile(() => subscriber1(sender, eventArgs), subscriberName); Profile(() => subscriber1(sender, eventArgs), subscriberName);
@@ -269,6 +308,9 @@ namespace ICD.Common.Utils.Timers
if (elapsed >= RED_MILLISECONDS) if (elapsed >= RED_MILLISECONDS)
color = eConsoleColor.Red; color = eConsoleColor.Red;
if (s_ProfileIndentCount > 0)
IcdConsole.Print(StringUtils.Repeat(" ", s_ProfileIndentCount - 1));
IcdConsole.Print(color, "{0:n}ms", elapsed); IcdConsole.Print(color, "{0:n}ms", elapsed);
IcdConsole.PrintLine(" to execute {0}", name); IcdConsole.PrintLine(" to execute {0}", name);
} }