Files
ICD.Common.Utils/ICD.Common.Utils/Timers/IcdStopwatch.cs
2018-03-09 13:49:13 -05:00

165 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using ICD.Common.Properties;
#if SIMPLSHARP
using Crestron.SimplSharp;
#else
using System.Diagnostics;
#endif
namespace ICD.Common.Utils.Timers
{
public sealed class IcdStopwatch
{
// Used with profiling
private const long YELLOW_MILLISECONDS = 100;
private const long RED_MILLISECONDS = 400;
private readonly Stopwatch m_Stopwatch;
#region Properties
public long ElapsedMilliseconds { get { return m_Stopwatch.ElapsedMilliseconds; } }
public bool IsRunning { get { return m_Stopwatch.IsRunning; } }
#endregion
#region Constructors
/// <summary>
/// Constructor.
/// </summary>
public IcdStopwatch()
: this(new Stopwatch())
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="stopwatch"></param>
public IcdStopwatch(Stopwatch stopwatch)
{
m_Stopwatch = stopwatch;
}
public static IcdStopwatch StartNew()
{
return new IcdStopwatch(Stopwatch.StartNew());
}
#endregion
#region Methods
/// <summary>
/// Stops the stopwatch at the current elapsed time.
/// </summary>
public void Stop()
{
m_Stopwatch.Stop();
}
/// <summary>
/// Starts or resumes the stopwatch from the current elapsed time.
/// </summary>
public void Start()
{
m_Stopwatch.Start();
}
/// <summary>
/// Stops the stopwatch and resets the elapsed time to 0.
/// </summary>
public void Reset()
{
m_Stopwatch.Reset();
}
/// <summary>
/// Resets the stopwatch and starts again from an elapsed time of 0.
/// </summary>
public void Restart()
{
Reset();
Start();
}
#endregion
#region Profiling
/// <summary>
/// Executes the action and prints the duration to the console.
/// </summary>
/// <param name="action"></param>
/// <param name="name"></param>
[PublicAPI]
public static void Profile(Action action, string name)
{
if (action == null)
throw new ArgumentNullException("action");
IcdStopwatch stopwatch = StartNew();
action();
PrintProfile(stopwatch, name);
}
/// <summary>
/// Executes the function and prints the duration to the console.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <param name="name"></param>
/// <returns></returns>
[PublicAPI]
public static T Profile<T>(Func<T> func, string name)
{
if (func == null)
throw new ArgumentNullException("func");
T output = default(T);
Profile(() =>
{
output = func();
}, name);
return output;
}
/// <summary>
/// Profiles getting each item from the enumerable.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumerable"></param>
/// <param name="name"></param>
/// <returns></returns>
public static IEnumerable<T> Profile<T>(IEnumerable<T> enumerable, string name)
{
using (IEnumerator<T> enumerator = enumerable.GetEnumerator())
{
while (Profile(() => enumerator.MoveNext(), name))
yield return enumerator.Current;
}
}
private static void PrintProfile(IcdStopwatch stopwatch, string name)
{
long elapsed = stopwatch.ElapsedMilliseconds;
eConsoleColor color = eConsoleColor.Green;
if (elapsed >= YELLOW_MILLISECONDS)
color = eConsoleColor.Yellow;
if (elapsed >= RED_MILLISECONDS)
color = eConsoleColor.Red;
IcdConsole.Print(color, "{0}ms", elapsed);
IcdConsole.PrintLine(" to execute {0}", name);
}
#endregion
}
}