Search code examples
c#.netstopwatch

Helper class for performance tests using StopWatch class


In this example code i am using a simple StopWatch to test time that it takes to complete a given task/action

StopWatch SW1 = new StopWatch();
SW1.Start();
SomeAction();
SW1.Stop();
sting results = SW1.Elapsed.ToString();
MessageBox.Show(resutls);

i would like to have a class that i will instantiate to use with tests

public Class PerformanceTests
{
   public StopWatch SW1 = new StopWatch();
   public StopWatch SW2 = new StopWatch();
   public string results1 = "", results2 = "";
   ....
   ....
   //some other variables to use 
}

though when instantiating the class and trying to use SW1 is not letting me use its methods. What am i doing wrong ?

PerformanceTests Ptst = new PerformanceTests();
Ptst.SW1. ... Start() is not accessible

Update

For rest of answers, don't copy the code from me, as I miss capitalized stopwatch. Instead of instantiating the Stopwatch class i accidentally didn't pay attention Visual Studio asking if i want to create a class for my so called stopwatch instead of .NET's real Stopwatch.

So my advice, pay attention to the suggested actions of Visual Studio intellisense even though it should be same all the time . Just make sure till you're really experienced and know all the classes by heart.


Solution

  • Here is simple class, which can help you for measuring time of code block execution:

    public class PerformanceTester : IDisposable
    {
        private Stopwatch _stopwatch = new Stopwatch();
        private Action<TimeSpan> _callback;
    
        public PerformanceTester()
        {
            _stopwatch.Start();
        }
    
        public PerformanceTester(Action<TimeSpan> callback) : this()
        {
            _callback = callback;            
        }
    
        public static PerformanceTester Start(Action<TimeSpan> callback)
        {
            return new PerformanceTester(callback);
        }
    
        public void Dispose()
        {
            _stopwatch.Stop();
            if (_callback != null)
                _callback(Result);
        }
    
        public TimeSpan Result
        {
            get { return _stopwatch.Elapsed; }
        }
    }
    

    Usage (just wrap code block with using of PerformanceTester):

    using (var tester = new PerformanceTester())
    {
        // code to test
        MessageBox.Show(tester.Results.ToString());
    }
    

    If you declare tester variable before using block, then stopwatch will stop automatically when you exit using block, and results will be available for you:

    PerformanceTester tester;
    
    using (tester = new PerformanceTester())    
        SomeAction();
    
    MessageBox.Show(tester.Results.ToString());
    

    If you pass callback action to PerformanceTester, then this action will be called at the end of using statement, and elapsed time will be passed to callback:

    using (PerformanceTester.Start(ts => MessageBox.Show(ts.ToString())))
         SomeAction();
    

    You can declare method, which will accept TimeSpan and process results:

    private void ProcessResult(TimeSpan span)
    {
       // log, show, etc
       MessageBox.Show(span.ToString());
    }
    

    Usage becomes very clean:

    using (PerformanceTester.Start(ProcessResult))
         SomeAction();