Measuring code execution time
Asked Answered
P

7

148

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)
Packard answered 4/5, 2013 at 15:59 Comment(5)
@Soner If I tagged it with C# is because C# code is welcome for me.Packard
possible duplicate of Find Execution time of a MethodPassivism
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 subjectFoolish
Possible duplicate of Is DateTime.Now the best way to measure a function's performance?Heisenberg
Possible duplicate of Calculate the execution time of a methodSkidproof
B
291

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);
Boom answered 4/5, 2013 at 16:0 Comment(5)
@ElektroHacker, you are welcome, its easier to use, plus it is more accurate then DateTime :)Boom
Please refer github.com/chai-deshpande/LogExec (a NUGET package is also available 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.Paralysis
@Boom 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?Orit
@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 codeBoom
But this does not measure the process time, so the result is affected by other processes running on the system.Merriemerrielle
G
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.

Gilletta answered 4/5, 2013 at 16:8 Comment(5)
can it used for execution time of each line of code? e.g: bindingSource.datasource = db.table; // how much it takes long?Cecrops
@Cecrops 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 on after every single line to calculate. Based on your line; take a look ideone.com/DjR6baMariande
i did a little trick on it to get the miliseconds out of picture. this way watch.Elapsed.ToString().Split('.')[0]Braga
@Braga Yeah, you can do that or you can use Custom Timespan Format Strings like stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss") which seems a cleaner way to me.Mariande
Best answer. Thanks!Ane
S
61

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

Schuler answered 5/6, 2016 at 9:8 Comment(3)
Thank, best answer so farSamos
Thanks, Was looking for such in centralized way. Have done this strategy with ActionFilter as well.Palacios
Not only this is a great answer, but also I learn something new from it too! Well Done Bud!Portemonnaie
E
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.

Eberhardt answered 1/10, 2014 at 7:15 Comment(0)
L
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.

Loxodromics answered 24/3, 2017 at 9:55 Comment(0)
Z
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.

Zita answered 16/4, 2018 at 11:25 Comment(0)
E
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)
Elysia answered 29/1, 2020 at 8:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.