144

I want to know how much time a procedure/function/order takes to finish, for testing purposes.

This is what I did but my method is wrong 'cause if the difference of seconds is 0 can't return the elapsed milliseconds:

Notice the sleep value is 500 ms so elapsed seconds is 0 then it can't return milliseconds.

    Dim Execution_Start As System.DateTime = System.DateTime.Now
    Threading.Thread.Sleep(500)

    Dim Execution_End As System.DateTime = System.DateTime.Now
    MsgBox(String.Format("H:{0} M:{1} S:{2} MS:{3}", _
    DateDiff(DateInterval.Hour, Execution_Start, Execution_End), _
    DateDiff(DateInterval.Minute, Execution_Start, Execution_End), _
    DateDiff(DateInterval.Second, Execution_Start, Execution_End), _
    DateDiff(DateInterval.Second, Execution_Start, Execution_End) * 60))

Can someone show me a better way to do this? Maybe with a TimeSpan?

The solution:

Dim Execution_Start As New Stopwatch
Execution_Start.Start()

Threading.Thread.Sleep(500)

MessageBox.Show("H:" & Execution_Start.Elapsed.Hours & vbNewLine & _
       "M:" & Execution_Start.Elapsed.Minutes & vbNewLine & _
       "S:" & Execution_Start.Elapsed.Seconds & vbNewLine & _
       "MS:" & Execution_Start.Elapsed.Milliseconds & vbNewLine, _
       "Code execution time", MessageBoxButtons.OK, MessageBoxIcon.Information)
Jim Aho
  • 9,932
  • 15
  • 56
  • 87
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • 1
    @Soner If I tagged it with C# is because C# code is welcome for me. – ElektroStudios May 04 '13 at 16:14
  • 2
    possible duplicate of [Find Execution time of a Method](http://stackoverflow.com/questions/16130232/find-execution-time-of-a-method) – Jesse May 04 '13 at 18:04
  • 2
    Besides the obvious reasons to use a stopwatch, you should never do any math with `DateTime.Now` due to Daylight Savings and Time Zone issues. Please read [my blog post on this very subject](http://codeofmatt.com/2013/04/25/the-case-against-datetime-now/) – Matt Johnson-Pint May 06 '13 at 00:18
  • 4
    Possible duplicate of [Is DateTime.Now the best way to measure a function's performance?](https://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance) – Michael Freidgeim Jun 19 '17 at 03:41
  • 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

7 Answers7

285

A better way would be to use Stopwatch, instead of DateTime differences.

Stopwatch Class - Microsoft Docs

Provides a set of methods and properties that you can use to accurately measure elapsed time.

// create and start a Stopwatch instance
Stopwatch stopwatch = Stopwatch.StartNew(); 

// replace with your sample code:
System.Threading.Thread.Sleep(500);

stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
juliand665
  • 2,664
  • 1
  • 16
  • 16
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 1
    @ElektroHacker, you are welcome, its easier to use, plus it is more accurate then DateTime :) – Habib May 04 '13 at 16:06
  • 1
    Please refer https://github.com/chai-deshpande/LogExec (a NUGET package is also available https://www.nuget.org/packages/LogExec/). This does the exact same things that @soner-gonul mentioned - but, the usage is clutter free and hides all the boilerplate code. Very helpful when you want to use it very frequently. It also uses Common.Logging so that you can integrate with your preferred logging provider. – Chai Jan 20 '14 at 04:11
  • 1
    @Habib can you please help me to understand why is Thread.sleep(500) is necessary? Cant i do it skipping sleep, would that make it less efficient? – Md Sifatul Islam Mar 19 '17 at 12:43
  • 12
    @Md.SifatulIslam, there is no need to use `Thread.Sleep`, it just there as a sample code to show delay.... in fact you should avoid using `Thread.Sleep` anywhere in your code – Habib Mar 20 '17 at 12:11
  • But this does not measure the process time, so the result is affected by other processes running on the system. – mcu Oct 05 '21 at 20:44
72

Stopwatch measures time elapsed.

// Create new stopwatch
Stopwatch stopwatch = new Stopwatch();

// Begin timing
stopwatch.Start();

Threading.Thread.Sleep(500)

// Stop timing
stopwatch.Stop();

Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);

Here is a DEMO.

Pang
  • 9,564
  • 146
  • 81
  • 122
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • can it used for execution time of each line of code? e.g: bindingSource.datasource = db.table; // how much it takes long? – vaheeds Jul 25 '13 at 06:44
  • 2
    @vaheeds Sure. Just start this `Stopwatch` on top of your each line and stop it after your each line. Remember, you need to use also [`Stopwatch.Reset`](http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.reset.aspx) on after every single line to calculate. Based on your line; take a look http://ideone.com/DjR6ba – Soner Gönül Jul 25 '13 at 06:48
  • i did a little trick on it to get the miliseconds out of picture. this way watch.Elapsed.ToString().Split('.')[0] – Doruk Sep 07 '16 at 07:50
  • 3
    @Doruk Yeah, you can do that or you can use [Custom Timespan Format Strings](https://msdn.microsoft.com/en-us/library/ee372287(v=vs.110).aspx) like `stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss")` which seems a cleaner way to me. – Soner Gönül Sep 07 '16 at 08:44
  • 1
    Best answer. Thanks! – tedi May 15 '17 at 10:50
60

You can use this Stopwatch wrapper:

public class Benchmark : IDisposable 
{
    private readonly Stopwatch timer = new Stopwatch();
    private readonly string benchmarkName;

    public Benchmark(string benchmarkName)
    {
        this.benchmarkName = benchmarkName;
        timer.Start();
    }

    public void Dispose() 
    {
        timer.Stop();
        Console.WriteLine($"{benchmarkName} {timer.Elapsed}");
    }
}

Usage:

using (var bench = new Benchmark($"Insert {n} records:"))
{
    ... your code here
}

Output:

Insert 10 records: 00:00:00.0617594

For advanced scenarios, you can use BenchmarkDotNet or Benchmark.It or NBench

Alex Erygin
  • 3,161
  • 1
  • 22
  • 22
16

If you use the Stopwatch class, you can use the .StartNew() method to reset the watch to 0. So you don't have to call .Reset() followed by .Start(). Might come in handy.

Marcell
  • 809
  • 8
  • 23
5

Stopwatch is designed for this purpose and is one of the best way to measure execution time in .NET.

var watch = System.Diagnostics.Stopwatch.StartNew();
/* the code that you want to measure comes here */
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;

Do not use DateTimes to measure execution time in .NET.

Pang
  • 9,564
  • 146
  • 81
  • 122
Sam
  • 111
  • 3
  • 7
5

If you are looking for the amount of time that the associated thread has spent running code inside the application.
You can use ProcessThread.UserProcessorTime Property which you can get under System.Diagnostics namespace.

TimeSpan startTime= Process.GetCurrentProcess().Threads[i].UserProcessorTime; // i being your thread number, make it 0 for main
//Write your function here
TimeSpan duration = Process.GetCurrentProcess().Threads[i].UserProcessorTime.Subtract(startTime);

Console.WriteLine($"Time caluclated by CurrentProcess method: {duration.TotalSeconds}"); // This syntax works only with C# 6.0 and above

Note: If you are using multi threads, you can calculate the time of each thread individually and sum it up for calculating the total duration.

Shailesh Prajapati
  • 458
  • 2
  • 7
  • 20
3

Example for how one might use the Stopwatch class in VB.NET.

Dim Stopwatch As New Stopwatch

Stopwatch.Start()
            ''// Test Code
Stopwatch.Stop()
Console.WriteLine(Stopwatch.Elapsed.ToString)

Stopwatch.Restart()            
           ''// Test Again

Stopwatch.Stop()
Console.WriteLine(Stopwatch.Elapsed.ToString)
Pang
  • 9,564
  • 146
  • 81
  • 122
Praxiom
  • 578
  • 1
  • 8
  • 21