Skip to content

Instantly share code, notes, and snippets.

@cmshawns
Last active August 29, 2015 14:10
Show Gist options
  • Save cmshawns/31d2a68703b7c4cc3f08 to your computer and use it in GitHub Desktop.
Save cmshawns/31d2a68703b7c4cc3f08 to your computer and use it in GitHub Desktop.
Record the time it takes to execute a block of code
using System.Diagnostics;
using System;
namespace MyNamespace
{
public enum TimerOutput
{
Debug,
Console
}
public class PerformanceTimer : IDisposable
{
#if DEBUG
private readonly Stopwatch _stopwatch = new Stopwatch();
private readonly string _label;
private readonly ConsoleTraceListener _outputListener;
/// <summary>
/// Initializes a new instance of the <see cref="PerformanceTimer"/> class.
/// </summary>
private PerformanceTimer()
{
_stopwatch.Start();
}
/// <summary>
/// Initializes a new instance of the <see cref="PerformanceTimer"/> class.
/// </summary>
protected PerformanceTimer(TimerOutput output) : this()
{
if (output == TimerOutput.Console)
{
this._outputListener = new ConsoleTraceListener { Name = "Console" };
}
}
/// <summary>
/// Initializes a new instance of the <see cref="PerformanceTimer"/> class.
/// </summary>
/// <param name="label"></param>
protected PerformanceTimer(string label) : this()
{
_label = label;
}
/// <summary>
/// Initializes a new instance of the <see cref="PerformanceTimer"/> class.
/// </summary>
/// <param name="label"></param>
/// <param name="output"></param>
protected PerformanceTimer(string label, TimerOutput output) : this(label)
{
if (output == TimerOutput.Console)
{
this._outputListener = new ConsoleTraceListener {Name = "Console"};
}
}
#endif
/// <summary>
/// Outputs the elapsed time that the <see cref="PerformanceTimer"/> was in scope.
/// </summary>
public void Dispose()
{
#if DEBUG
_stopwatch.Stop();
TimeSpan elapsed = _stopwatch.Elapsed;
if (_outputListener != null)
{
Debug.Listeners.Add(this._outputListener);
}
if (string.IsNullOrWhiteSpace(_label))
{
Debug.WriteLine("Elapsed: {0}", elapsed);
}
else
{
Debug.WriteLine("{0} - Elapsed: {1}", _label, elapsed);
}
if (_outputListener != null && Debug.Listeners.Contains(_outputListener))
{
Debug.Listeners.Remove(_outputListener);
}
#endif
}
public static IDisposable Start(string label)
{
#if DEBUG
return new PerformanceTimer(label);
#else
return null;
#endif
}
public static IDisposable Start(string label, TimerOutput output)
{
#if DEBUG
return new PerformanceTimer(label, output);
#else
return null;
#endif
}
}
}
@cmshawns
Copy link
Author

Usage

Wrap the code you want to measure in a using which instantiates PerformanceTimer:

  using (new PerformanceTimer(">> Long running code"))
  {
    // block of code you want to measure
  }

@cmshawns
Copy link
Author

Improvements:

  • PerformanceTimer now handles conditional compilation internally, so it is no longer necessary to wrap the beginning and ending of the using.
  • Use the new Start() factory method instead of constructors.
  • Outputs to the Debug window by default.
  • Redirect output to the Console by specifying TimerOutput.Console:
using (PerformanceTimer.Start("Console", TimerOutput.Console))
{
    Thread.Sleep(1000);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment