calculate execution time of my program - c#

im actually doing a tool, where every ms counts, and i want to debug my program to see where is it slow and where its fast enough, cause somewhere it goes slowly, the program is like 600lines, is there any way to see execution time of EVERY function in my program? i could only find this method
Stopwatch stopWatch = Stopwatch.StartNew();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
but i saw its not actually so accurate and i need it to be as accurate as possible. thanks!

I ran the following:
var stopWatch = Stopwatch.StartNew();
Thread.Sleep(1000);
stopWatch.Stop();
Console.WriteLine(stopWatch.Elapsed);
The output was 00:00:01.0002463, please note that in this case, you might expect a second (reasonable expectation), but, it's slightly over a second. Why? Thread.Sleep() isn't particularly accurate! Stopwatch is accurate enough to demonstrate that, and is in fact, generally accurate to nanosecond resolution.
That said, you're going about this the wrong way if you're trying to use stopwatches, you should instead profile your application with something like dotTrace and see what the hot spots are.

Related

C# performance counter Timer100Ns. How to?

I have an application which monitors a particular event and then starts to calculate things once it happens. Events are irregular and can come in any pattern from bunches in a sec to none for long time..
I want to measure %% of time the application is busy (similar to CPU % Usage)
I want to use Timer100Ns counter
Two questions:
Do I increment it by hardware ticks or by DateTime ticks (e.g. if I use Stopwatch - do I use sw.ElapsedTicks or sw.Elapsed.Ticks) ?
Do I need a base counter for it?
so I am about to write something like this:
Stopwatch sw = new Stopwatch();
sw.Start();
// Do some operation which is irregular by nature
sw.Stop();
// Measure utilization of the application
myCounterOfTypeTimer100Ns.IncrementBy(sw.Elapsed.Ticks);
Will it do ?
EDIT : I experimented with it a bit and now its even more confusing.. It actually shows the values I increment it by. Not %%.
The mystery unravelled. It currently appears that I don't use it in the way it was supposed to be used (or rather I didn't read TFM properly). If the sampling interval is 1s (as in perf mon live window) and you intervals are more than 1s then it shows you a nonsense number... To achieve smoothness, the activity you are trying to measure must be really fractions of 1s.. Otherwise this counter is not a good idea..
The answer for this kind of problem (although its not obvious, but still disturbing that nobody suggested it in a week) is actually SampleCounter.

Get milliseconds passed

A just need a stable count of the current program's progression in milliseconds in C#. I don't care about what timestamp it goes off of, whether it's when the program starts, midnight, or the epoch, I just need a single function that returns a stable millisecond value that does not change in an abnormal manner besides increasing by 1 each millisecond. You'd be surprised how few comprehensive and simple answers I could find by searching.
Edit: Why did you remove the C# from my title? I'd figure that's a pretty important piece of information.
When your program starts create a StopWatch and Start() it.
private StopWatch sw = new StopWatch();
public void StartMethod()
{
sw.Start();
}
At any point you can query the Stopwatch:
public void SomeMethod()
{
var a = sw.ElapsedMilliseconds;
}
If you want something accurate/precise then you need to use a StopWatch, and please read Eric Lippert's Blog (formerly the Principal Developer of the C# compiler Team) Precision and accuracy of DateTime.
Excerpt:
Now, the question “how much time has elapsed from start to finish?” is a completely different question than “what time is it right now?” If the question you want to ask is about how long some operation took, and you want a high-precision, high-accuracy answer, then use the StopWatch class. It really does have nanosecond precision and accuracy that is close to its precision.
If you don't need an accurate time, and you don't care about precision and the possibility of edge-cases that cause your milliseconds to actually be negative then use DateTime.
Do you mean DateTime.Now? It holds absolute time, and subtracting two DateTime instances gives you a TimeSpan object which has a TotalMilliseconds property.
You could store the current time in milliseconds when the program starts, then in your function get the current time again and subtract
edit:
if what your going for is a stable count of process cycles, I would use processor clocks instead of time.
as per your comment you can use DateTime.Ticks, which is 1/10,000 of a millisecond per tick
Also, if you wanted to do the time thing you can use DateTime.Now as your variable you store when you start your program, and do another DateTime.Now whenever you want the time. It has a millisecond property.
Either way DateTime is what your looking for
It sounds like you are just trying to get the current date and time, in milliseconds. If you are just trying to get the current time, in milliseconds, try this:
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

Why is the first iteration always faster then the next in a loop?

I would like to understand why the first iteration in the loop executes quicker than the rest.
Stopwatch sw = new Stopwatch ();
sw.Start ();
for(int i=0; i<10; i++)
{
System.Threading.Thread.Sleep ( 100 );
Console.WriteLine ( "Finished at : {0}", ((double) sw.ElapsedTicks / Stopwatch.Frequency ) * 1e3 );
}
When I execute the code I get the following:
Initially I thought it could be due to the accuracy factor of Stopwatch class, but then why is it applicable only to the first element? Correct me if I'm missing something.
This is a very flawed benchmark. For one, Thread.Sleep does not guarantee you that you'll sleep for exactly 100ms. Try much longer sleeps and you'll see more consistent results.
So it might be even just scheduling - the next iterations are always just doing sleep after sleep. Since Sleep works thanks to the system interrupt clock, the sleeps after the first should take similar amount of time, while the first has to "sync up" with the clock first.
If you add another sleep before the cycle (and before starting the stopwatch), you'll likely get closer times for each of the iterations.
Or even better, don't use sleeps. If you use some actual CPU work instead, you'll avoid thread switches (provided you've got enough CPU to do that) and many other costs not associated with the cycle itself. For example,
Stopwatch sw = new Stopwatch ();
sw.Start ();
for(int i=0; i<10; i++)
{
Thread.SpinWait(10000000);
Console.WriteLine ( "Finished at : {0}", ((double) sw.ElapsedTicks / Stopwatch.Frequency ) * 1e3 );
}
This will give you much more consistent results, because it doesn't depend on the clock at all.
There's many other things that can complicate a benchmark like this, which is why benchmarks simply aren't done this way. There will always be deviations, and they can get rather big, especially on a system with a lot of work.
In other words, if you're getting differences in CPU work execution time on the scale of milliseconds, someone is stealing your work. There's nothing in a modern CPU that would account for such a huge difference just based on e.g. i++ being there or not.
I could describe a lot more issues with your code, but it probably isn't worth it. Just google for some best practices on CPU work benchmarking in C#, and you'll get much more worth out of it.
Oh, and just to help hammer the point home more, on my computer, the first tends to go anywhere from 99 up to 100. This would be highly unusual, since the default is 15.6ms, rather than 1ms, but the culprit is easily found - Chrome sets it to 1ms. Ouch.
What you're outputting for times is the total time elapsed since the start. so, time increasing by about 100ms is exactly what you should be expecting
But, when you use Thread.Sleep you're giving up control of the thread and maybe for something close to the time you've specified. That time will be in multiples of the system quantum--so, what you specify cannot possibly be exact. If other threads of higher priority are doing work, it's less likely that your thread will be given processor time at a granularity close to the time you've suggested.

Execute same method consume far less time

When I analyzed my old posts exact solution, I found a contradiction so I try to code this in Form1 constructor (after InitializeComponent();)
Stopwatch timer = Stopwatch.StartNew();
var timeStartGetStatistic = DateTime.Now.ToString("HH:mm:ss:fff");
var timeEndGetStatistic = DateTime.Now.ToString("HH:mm:ss:fff");
timer.Stop();
Console.WriteLine("Convert take time {0}", timer.Elapsed);
Console.WriteLine("First StopWatch\nStart:\t{0}\nStop:\t{1}",
timeStartGetStatistic, timeEndGetStatistic);
Stopwatch timer2 = Stopwatch.StartNew();
var timeStartGetStatistic2 = DateTime.Now.ToString("HH:mm:ss:fff");
var timeEndGetStatistic2 = DateTime.Now.ToString("HH:mm:ss:fff");
timer2.Stop();
Console.WriteLine("Convert take time {0}", timer2.Elapsed);
Console.WriteLine("Second StopWatch\nStart:\t{0}\nStop:\t{1}",
timeStartGetStatistic2, timeEndGetStatistic2);
Result
Convert take time 00:00:00.0102284
First StopWatch
Start: 02:42:29:929
Stop: 02:42:29:939
Convert take time 00:00:00.0000069
Second StopWatch
Start: 02:42:29:940
Stop: 02:42:29:940
I found that only FIRST DateTime.Now.ToString("HH:mm:ss:fff"); consumes 10ms but 3 others consume less than 10us in same scope, may I know the exact reason?
Is it because the FIRST one make the code on the memory so the following 3 get the advantage of it to consume more less time to do the same things? thanks.
At first, I thought it was indeed the JIT.. but it doesn't make sense because the framework itself is compiled AOT, when installed.
I think it is loading the current culture (ToString does that, and indeed it is the function that takes time)
================ EDIT =============
I did some tests, and there are two things which take time the first time they are called.
DateTime.Now make a call to the internal method TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc which take about half of the consumed time...
the rest is consumed by to string..
if instead of calling DateTime.Now you had called DateTime.UtcNow, you wouldn't notice that first-time impact of getting the local time offset.
and about ToString - what's consuming most of it's running time, was generating the DateTimeFormat for the current culture.
I think this answered your question pretty well :)
First call to any individual method from a class requires JIT so first call is always slow (unless assembly pre-JITed with NGen).
There also additional cost to load necessary resources/data depending on method associated with first call. I.e. likely DateTime.Now and DateTime.ToString require some locale data to be loaded/preprocessed.
Standard way to measure performance with Stopwatch is to call function/code that you want to measure once to kick all JIT related to the code and than do measurement. Usually you'd run code many times and average results.
// --- Warm up --- ignore time here unless meauring startup perf.
var timeStartGetStatistic = DateTime.Now.ToString("HH:mm:ss:fff");
var timeEndGetStatistic = DateTime.Now.ToString("HH:mm:ss:fff");
// Actual timing after JIT and all startup cost is payed.
Stopwatch timer2 = Stopwatch.StartNew();
// Consider multiple iterations i.e. to run code for about a second.
var timeStartGetStatistic2 = DateTime.Now.ToString("HH:mm:ss:fff");
var timeEndGetStatistic2 = DateTime.Now.ToString("HH:mm:ss:fff");
timer2.Stop();
Console.WriteLine("Convert take time {0}", timer2.Elapsed);
Console.WriteLine("Second StopWatch\nStart:\t{0}\nStop:\t{1}",
timeStartGetStatistic2, timeEndGetStatistic2);
As already noted you're measuring wrong. You should not include first call to any code as it needs to be jited, that time will be included.
Also it is not good to rely on result just ran only once; You need to run the code number of times and you should be calculating the average time taken.
Be sure that you do it in release mode without debugger attached.

Elapsed time from start to finish with 20 ms precision

From this article http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx:
Now, the question “how much time has elapsed from start to finish?” is a completely different question than “what time is it right now?” If the question you want to ask is about how long some operation took, and you want a high-precision, high-accuracy answer, then use the StopWatch class. It really does have nanosecond precision and accuracy that is close to its precision.
The question is - what should I use if I need elapsed time from start to finish and I need 20 ms precision?
StopWatch has much better precision so I'm afraid that I will pay processor time for "extra-precision" which I don't need.
DateTime.Now has exactly precision I need but it also has a lot of extra-stuff like Month, Year etc. and I'm again afraid that this makes it much slower.
This article should help you:
http://www.dijksterhuis.org/timing-function-performance-stopwatch-class/
In general it says that the Stopwatch is the better choice, which is even my personal opinion.
The only (considerable?) overhead of the StopWatch is the incorporation of QueryPerformanceFrequency determining if the StopWatch will go on with high resolution frequency or not. Actually it is an overhead only if it will go without high resolution frequency. Otherwise is a faster option as it gets the timestamp with a WIN32 QueryPerformanceCounter call instead of DateTime.UtcNow.Ticks.
From what I read on the internet untill now StopWatch class from System.Diagnostics namespace is the best class used for timing.
If you want precision under 1 ms remember to use the Elapsed.TotalMilliseconds property to retrieve elapsed time, sw.ElapsedMilliseconds jumps in increments of 1 ms.
using System;
using System.Diagnostics;
namespace MySolution
{
class Program
{
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
// code to be timed here
sw.Stop();
Console.WriteLine("Run time in ms = {0}", sw.Elapsed.TotalMilliseconds);
}
}
}

Categories

Resources