59

I want to see how long a function is running. So I added a timer object on my form, and I came out with this code:

private int counter = 0;

// Inside button click I have:
timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);
timer.Stop();

And:

private void timer_Tick(object sender, EventArgs e)
{
    counter++;
    btnTabuSearch.Text = counter.ToString();
}

But this is not counting anything. Why?

Venkat
  • 2,549
  • 2
  • 28
  • 61
sebastian.roibu
  • 2,579
  • 7
  • 37
  • 59
  • if you set timer.stop(); after Start() is normal. When is necessary to stop timer? When function is finished? – Roberto Conte Rosito Apr 11 '12 at 13:44
  • 3
    why not StopWatch? (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) – VJAI Apr 11 '12 at 13:46
  • Possible duplicate of [Measuring code execution time](https://stackoverflow.com/questions/16376191/measuring-code-execution-time) – Michael Freidgeim Jun 19 '17 at 03:37
  • Possible duplicate of [Calculate the execution time of a method](https://stackoverflow.com/questions/14019510/calculate-the-execution-time-of-a-method) – StayOnTarget Mar 27 '19 at 19:53

11 Answers11

62

To avoid future problems with a timer, here is the right code:

timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = 1; //set interval on 1 milliseconds
timer.Enabled = true; //start the timer
Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);
timer.Enabled = false; //stop the timer

private void timer_Tick(object sender, EventArgs e)
{
   counter++;
   btnTabuSearch.Text = counter.ToString();
}

But it's the wrong aproach. You must use the Stopwatch (System.Diagnostic) class because it's a High resolution timer and the word Diagnostic says everything.

So try this:

Stopwatch timer = Stopwatch.StartNew();

Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);

timer.Stop();  
TimeSpan timespan = timer.Elapsed;

btnTabuSearch.Text = String.Format("{0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10);
Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
Omar
  • 16,329
  • 10
  • 48
  • 66
  • 4
    Note: with the timer set with an interval of 1ms, you should be careful not to think that your counter is actually the number of milliseconds. Depending on hardware, the minimum interval for a timer (on my computer) is around 15ms. So even if you set the interval to 1ms, it'll only fire every 15ms or so. – Matt Burland Apr 11 '12 at 14:14
  • i will try the timer tomorrow. I just want a counter to see how much time passed since i pressed the button. – sebastian.roibu Apr 11 '12 at 19:37
  • 3
    `var timer = Stopwatch.StartNew();` <-- one less line of code – Ian Mercer Jan 31 '13 at 17:18
  • The answaer is not correct. `Timer()` code does not work anymore. – Sebastian Xawery Wiśniowiecki Nov 08 '16 at 15:52
56

Don't use a timer - use the Stopwatch class.

var sw = new Stopwatch();
Result result = new Result();

sw.Start();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);

sw.Stop();

// sw.Elapsed tells you how much time passed
Oded
  • 489,969
  • 99
  • 883
  • 1,009
15

The best way to see how long a bit of code takes to run is to use System.Diagnostics.Stopwatch.

Here's an example:

using System.Diagnostics;

#if DEBUG
     Stopwatch timer = new Stopwatch();
     timer.Start();
#endif

     //Long running code

#if DEBUG
     timer.Stop();
     Debug.WriteLine("Time Taken: " + timer.Elapsed.TotalMilliseconds.ToString("#,##0.00 'milliseconds'"));
#endif

I use the #if DEBUG to ensure the stopwatch code doesn't get into the production release, but you could do without it.

Alain
  • 26,663
  • 20
  • 114
  • 184
15

Visual Studio 2015, 2017 Professional and Enterprise has diagnostic tool. If you have a breakpoint at the end of your function, it will display the time and duration under the Events tab as shown in the image:

Enter image description here

You can see the article Diagnostic Tools debugger window in Visual Studio 2015 for more details.

PS; So far only Xamarin forms, cross platform project doesnt support this feature. I wish that Microsoft brings this great feature for xamarin forms projects as well.

Emil
  • 6,411
  • 7
  • 62
  • 112
11

You should use the stopwatch class for timing functions.

Try the following:

private int counter = 0;

// setup stopwatch and begin timing
var timer = System.Diagnostics.Stopwatch.StartNew();

Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);

// stop timer and get elapsed time
timer.Stop();
var elapsed = timer.Elapsed;

// display result time
MessageBox.Show(elapsed.ToString("mm':'ss':'fff"));
Tot Zam
  • 8,406
  • 10
  • 51
  • 76
james lewis
  • 2,486
  • 3
  • 24
  • 30
8

Use Stopwatch of System.Diagnostics:

static void Main(string[] args)
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    Thread.Sleep(10000);
    stopWatch.Stop();

    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine("RunTime " + elapsedTime);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • 3
    Wouldn't it be easier to print the time with `ts.ToString("hh:mm:ss.ff")` or `ts.ToString("G")`? – Oliver Apr 11 '12 at 13:53
6

For timing a function, you should use the Stopwatch Class

Also, the reason your timer isn't counting is because you didn't set an interval for it.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
6

A possibility is to write once an helper method like that:

    public static void Time(Action action)
    {
        Stopwatch st = new Stopwatch();
        st.Start();
        action();
        st.Stop();
        Trace.WriteLine("Duration:" + st.Elapsed.ToString("mm\\:ss\\.ff"));
    }

and use it everywhere else to mesure the time like that:

    Time(() =>
    {
     CallOfTheMethodIWantToMeasure();
    });
Philippe
  • 28,207
  • 6
  • 54
  • 78
4

I reviewed and agreed with all suggestions. But wanted to share one generic implementation for execution time logger where we do not want to implement Stopwatch logic multiple times but still wants to measure execution time for multiple methods.

The main reason for not to implement logger in generic way is - method execution is in between stopwatch.Start() and stopwatch.Stop() also we may require method result after the execution for further processing.

So to tackle this issue I created following sample implementation where Execution time is logged separately without mixing it with actual method flow.

public static class Helper
{
    public static T Time<T>(Func<T> method, ILogger log)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var result = method();
        stopwatch.Stop();
        log.Info(string.Format("Time Taken For Execution is:{0}", stopwatch.Elapsed.TotalMilliseconds));
        return result;
    }
}

public class Arithmatic
{
    private ILogger _log;
    public Arithmatic(ILogger log)//Inject Dependency
    {
        _log = log;
    }

    public void Calculate(int a, int b)
    {
        try
        {
            Console.WriteLine(Helper.Time(() => AddNumber(a, b), _log));//Return the result and do execution time logging
            Console.WriteLine(Helper.Time(() => SubtractNumber(a, b), _log));//Return the result and do execution time logging
        }
        catch (Exception ex)
        {
            _log.Error(ex.Message, ex);
        }
    }

    private string AddNumber(int a, int b)
    {
        return "Sum is:" + (a + b);
    }

    private string SubtractNumber(int a, int b)
    {
        return "Subtraction is:" + (a - b);
    }
}

public class Log : ILogger
{
    public void Info(string message)
    {
        Console.WriteLine(message);
    }

    public void Error(string message, Exception ex)
    {
        Console.WriteLine("Error Message:" + message, "Stacktrace:" + ex.StackTrace);
    }
}

public interface ILogger
{
    void Info(string message);
    void Error(string message, Exception ex);
}

Calling Part:

 static void Main()
 {
    ILogger log = new Log();
    Arithmatic obj = new Arithmatic(log);
    obj.Calculate(10, 3);
    Console.ReadLine();
 }
Sumit Deshpande
  • 2,155
  • 2
  • 20
  • 36
  • interesting idea. Thanks for posting. – sebastian.roibu Sep 02 '16 at 06:13
  • don't you think the code contains too much unrelated info, I believe only the helper method and its usage in one line is enough – mkb Sep 15 '17 at 14:17
  • 1
    Some extend i agree but information is not unrelated if one wants to use this concept at broader/enterprise level then he has to consider all this information like logger and all. So I just mentioned detailed way of implementation. – Sumit Deshpande Sep 15 '17 at 17:30
1

record the time when current step begins to process

DateTime dtStart = DateTime.Now;

//Calculate the total number of milliseconds request took (Timespan = to represent the time interval)-> current - started time stamp ...
//TotalMilliseconds -->Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds.
// to measure how long a function is running 
var result=((TimeSpan)(DateTime.Now - dtStart)).TotalMilliseconds.ToString("#,##0.00") + "ms";
Leonardo Alves Machado
  • 2,747
  • 10
  • 38
  • 53
1

To view elapsed milliseconds betweeen breakpoints when debugging code, Visual Studio provides PerfTips, it's a built-in, useful and fast tool.

yu yang Jian
  • 6,680
  • 7
  • 55
  • 80