Measuring code execution time - c#

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)

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);

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.

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

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.

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.

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.

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)

Related

.NET 6 PeriodicTimer with top-of-the-minute timing

.NET 6 introduced the PeriodicTimer.
I need to do something every minute, at the top of the minute. For example: 09:23:00, 09:24:00, 09:25:00, ...
But with a one minute period - new PeriodicTimer(TimeSpan.FromMinutes(1)) - and starting at 09:23:45, I will get "ticks" at: 09:24:45, 09:25:45, 09:26:45, ...
So it's dependent on the start time.
My workaround is a one-second period, and a check that the current time has seconds equal to 0. Another workaround is to wait for the next minute and then start the timer. Both approaches work but are fiddly and use too fine a resolution.
Is there a built-in or better way to trigger at the top of the minute rather than one-minute-after-start?
AFAIK there is nothing like this available in the standard .NET libraries. And I don't think that it's likely to be added any time soon. My suggestion is to use the third party Cronos library, that does a good job at calculating time intervals¹. You can find a usage example here, by Stephen Cleary. What this library does is to take a DateTime and a Cron expression as input, and calculate the next DateTime that satisfies this expression. It is just a DateTime calculator, not a scheduler.
If you want to get fancy you could include the functionality of the Cronos library in a custom PeriodicTimer-like component, like the one below:
using Cronos;
public sealed class CronosPeriodicTimer : IDisposable
{
private readonly CronExpression _cronExpression; // Also used as the locker
private PeriodicTimer _activeTimer;
private bool _disposed;
private static readonly TimeSpan _minDelay = TimeSpan.FromMilliseconds(500);
public CronosPeriodicTimer(string expression, CronFormat format)
{
_cronExpression = CronExpression.Parse(expression, format);
}
public async ValueTask<bool> WaitForNextTickAsync(
CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
PeriodicTimer timer;
lock (_cronExpression)
{
if (_disposed) return false;
if (_activeTimer is not null)
throw new InvalidOperationException("One consumer at a time.");
DateTime utcNow = DateTime.UtcNow;
DateTime? utcNext = _cronExpression.GetNextOccurrence(utcNow + _minDelay);
if (utcNext is null)
throw new InvalidOperationException("Unreachable date.");
TimeSpan delay = utcNext.Value - utcNow;
Debug.Assert(delay > _minDelay);
timer = _activeTimer = new(delay);
}
try
{
// Dispose the timer after the first tick.
using (timer)
return await timer.WaitForNextTickAsync(cancellationToken)
.ConfigureAwait(false);
}
finally { Volatile.Write(ref _activeTimer, null); }
}
public void Dispose()
{
PeriodicTimer activeTimer;
lock (_cronExpression)
{
if (_disposed) return;
_disposed = true;
activeTimer = _activeTimer;
}
activeTimer?.Dispose();
}
}
Apart from the constructor, the CronosPeriodicTimer class has identical API and behavior with the PeriodicTimer class. You could use it like this:
var timer = new CronosPeriodicTimer("0 * * * * *", CronFormat.IncludeSeconds);
//...
await timer.WaitForNextTickAsync();
The expression 0 * * * * * means "on the 0 (zero) second of every minute, of every hour, of every day of the month, of every month, and of every day of the week."
You can find detailed documentation about the format of the Cron expressions here.
The 500 milliseconds _minDelay has the intention to prevent the remote possibility of the timer ticking twice by mistake. Also because the PeriodicTimer class has a minimum period of 1 millisecond.
For an implementation that uses the Task.Delay method instead of the PeriodicTimer class, and so it can be used by .NET versions previous than 6.0, you can look at the 3rd revision of this answer.
¹ With the caveat that the Cronos library is currently capped to the year 2099 (version 0.7.1).
For completeness, here are the workarounds mentioned in my question.
Tick every second, and wait for top-of-the-minute:
var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync(cancellationToken)) {
if (DateTime.UtcNow.Second == 0)
await DoSomething();
}
Delay till top-of-the-minute, then tick every minute:
var delay = (60 - DateTime.UtcNow.Second) * 1000; // take milliseconds into account to improve start-time accuracy
await Task.Delay(delay);
var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
while (await timer.WaitForNextTickAsync(cancellationToken)) {
await DoSomething();
}
Some notes about accuracy:
This will never be perfectly accurate, as discussed in the comments above. But it's good enough in many cases.
Small clock drifts will occur and make the per-minute timer more and more inaccurate, and this will only be fixed when the server is restarted. But the per-second timer "self-corrects" on every tick, so although it's "heavier", it will be more accurate over time.
The per-second timer can sometimes lose a tick or get a double tick (see comments above). The per-minute timer won't lose ticks, but they may be inaccurate. Whether this matters is something for you to consider.

How do I measure execution time for each row in C#

I have the following Selenium test:
[TestMethod]
public void Edit()
{
Driver.GoToAdministrera();
Driver.ClickLink(strings.ActorSettings);
Driver.SendKeysToId(text, "Attributes");
Driver.Navigate().Refresh();
Driver.AssertTextInId(string.Empty, "Attributes");
Driver.SendKeysToId(text, "Attributes");
Driver.ClickClass("submitbutton");
Thread.Sleep(3000);
Driver.Navigate().Refresh();
Driver.AssertTextInId(text, "Attributes");
}
It is slow and I want to analyze where the bottleneck is. I know I could profile the test, but that will give me some long stack-trace and hotspots. I just want to know how long the execution time is for each row.
I know I can use the StopWatch class. I can even do something like a help method for this:
protected static void Time(Action action)
{
var sw = new Stopwatch();
sw.Reset();
sw.Start();
action();
sw.Stop();
Console.WriteLine(sw.Elapsed + " " + action.Method.Name);
}
But this requires me to modify my test.
Does anyone know of a method to get the timings for each row in a piece of code executed?
If you use Visual Studio 2015 or later you can run the test under debugger and look for PerfTips values. Stepping from line to line you will get estimated value of elapsed time for each line of the test which is probably what you need.
DateTime start = DateTime.Now;
// Do Processing
Driver.GoToAdministrera();
DateTime end = DateTime.Now;
Console.WriteLine("Time taken : " + (end - start));

Is this the best way to get the time it takes to run an async task?

I want to find out how long it takes to execute my async tasks, so that I can improve on the execution time.
Please look at the test method and advise. Test background: I want to find out the user account manager from Active Directory given the sAMACcountName.
[TestMethod]
public async Task GetManagerAsync_TestMethod()
{
// connect to the Active Directory
var serviceUsers = new User(#"LDAP://XXXXXXXXX", #"USER", "PASSWORD");
// get the time before the start of operation
var sTime = DateTime.Now;
// perform the task
var task = await serviceUsers.GetManagerAsync(#"sAMAccountName");
// get the time after the operation
var eTime = DateTime.Now;
// get the time span between the start and end time
TimeSpan taskRunTime = eTime - sTime;
System.Diagnostics.Debug.WriteLine("Operation took {0} seconds", taskRunTime.TotalSeconds);
Assert.IsNotNull(task);
}
You should be using a Stopwatch instead.
var stopwatch = Stopwatch.StartNew();
var task = await serviceUsers.GetManagerAsync(#"sAMAccountName");
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
Not only is it more semantically correct, it's also way more accurate:
If the installed hardware and operating system support a high-resolution performance counter, then the Stopwatch class uses that counter to measure elapsed time. Otherwise, the Stopwatch class uses the system timer to measure elapsed time.

Calculate code run time/speed

I am very curious about run time/speed about codes in ms visual studio.
As instance,
1. code:
byte[] buffer = new byte[4096];
var p = System.IO.Directory.GetFiles(directoryName);
2. code
var entry = new ZipEntry(Path.GetFileName(file));
entry.DateTime = DateTime.Now;
If i run 1. code ı want to see "it's running time/speed 0.03 seconds"
If i run 2. code ı want to see "it's running time/speed 0.06 seconds"
Is there anything to calculate running time/speed of codes in c# without using timer ?
Any help will be appreciated.
Thanks.
The best thing to use for quickly profiling code is Stopwatch in System.Diagonstics
var sw = Stopwatch.StartNew();
///.... stuff
sw.Stop();
sw.ElapsedMilliseconds;
If this is something you may want to use in production, i'd recommend: http://miniprofiler.com/
You can use a Stopwatch for benchmarking code
var sw = Stopwatch.StartNew();
var entry = new ZipEntry(Path.GetFileName(file));
sw.Stop();
Console.WriteLine("Time to zip: {0}", sw.Elapsed);
You could create a helper method if you intend on doing using it a lot
public static TimeSpan Benchmark(Action action)
{
var sw = Stopwatch.StartNew();
action();
sw.Stop();
return sw.Elapsed;
}
...
var timeTaken = Benchmark(() => /* run some code */)
Typically one would use the stopwatch.startnew, stop, elapsedtime methods.
There are some profiling tools on the market, and microsoft also has its own built-in performance suite. The following link is a tutorial on how to set it up.
http://msdn.microsoft.com/en-us/library/ms182372.aspx

sleep-until in c#

I want to run a function periodically every 1 second, so after 10 seconds it is executed 10 times.
The simplest approach is using a loop like this :
while(true)
{
Thread.Sleep(1000);
function();
}
But the main problem with this approach is that it will not provide any periodic guarantees.
I mean if it takes 0.1 seconds to run function() the executions time of the function will be like this :
0, 1.1 , 2.2, 3.3, 4.4 , ...
As I remember, in real time language ADA we have a function sleep-until(#time). Now I'm looking for an alternative in C#.
Any sample code will be appreicated.
System.Threading.Timer timer = new System.Threading.Timer(ThreadFunc, null, 0, 1000);
private static void ThreadFunc(object state)
{
//Do work in here.
}
See MSDN for more info.
You can use Stopwatch to measure the time. I would also use a For-Loop instead.
var sw = new System.Diagnostics.Stopwatch();
var timeForOne = TimeSpan.FromSeconds(1);
var count = 10;
for(int i = 0; i < count; i++)
{
sw.Restart();
function();
sw.Stop();
int rest = (timeForOne - sw.Elapsed).Milliseconds;
if (rest > 0)
System.Threading.Thread.Sleep(rest);
}
To invoke something after specific interval of time you should use Timer class.
Here is the Tutorial

Categories