Checking to see how often a method is executed in C# - c#

I was wondering if its possible to check how frequently, in terms of an accurate timespan, a certain method gets executed in C#?
For example I have a device (a microphone), and once I start the microphone, its StartCollectingSamples event is fired which will in turn start invoking the Microphone_CollectSampleData() method.
How can I check how frequently this event is being raised? I place a breakpoint on Microphone_CollectSampleData() and it seems to get executed very frequently, possible 2/3 times a second, but how can I get that accurate time value?

Depending on the version of the visual studio you got, you can use the provided profiler, to analyze how many time each method is executed, how long it runs, etc.
There are other, non microsoft products, which aim to do the same, such as antz profiler, but they usually cost money after a trial period.

Related

How to work around intentional waits which are causing false hot paths when profiling?

I'm pretty new to profiling so I don't know how to even approach this issue. Basically, I want to discover why some hiccups in the UI are occurring. Profiler seems to be made for solving these kinds of issues so I went with that. I'm using Visual Studio 2010 on a Windows 8 machine so my only option is instrumentation profiling.
Unfortunately, what I get is a bunch of distracting hot paths that occur because of MessageBox.Show calls and long-running threads waiting for data with Monitor.Wait. These methods, of course, take orders of magnitude longer than the issues I'm trying to understand.
Is there no way to somehow filter-out these long-running methods? Ideally by function name or some other criteria, perhaps elapsed exclusive time.
Profiling is not for UI. Profiling is for calculations and other logic. If you really need to profile UI (which you should not) you can hide message boxes and simulate button clicks. Something like:
#if PROFILE_VERSION
DialogResult result = DialogResult.OK;
#else
DialogResult result = MessageBox.Show();
#endif
Of course you'll need to define PROFILE_VERSION and create new configuration for this.
But really, you should only test your logic.
Aside from hot paths being some of the pointless information profilers give you, here is how I would approach finding your "hiccups".
Most of the time I use random pausing.
I try to collect samples during the slow times (the "hiccups") so I can see what it's doing in that time.
If I get samples that I can see are not relevant, I just ignore those.
If the hiccups happen too fast to do that, there's a more difficult method.
It requires setting a few-millisecond timer interrupt with a handler.
When the suspect code starts, it enables the timer, and when it finishes it disables the timer.
That way, if it takes longer than normal to finish, the timer goes off. If I set a breakpoint in the handler, I can look to see what the program was doing when the timer went off.
That's a way to get a sample.
If I get several samples, that's usually enough to show the problem.

How robust is repeating a piece of code to measure it's execution time?

Let's say I want to measure how long MyFunction() executes.
Let's also say that MyFunction() executes fast (a few milliseconds) and that Stopwatch cannot measure the function time with a good enough precision.
I then will put MyFunction() inside of a loop which executes 1,000,000 times and measure that. I will time the execution of the loop and then divide the result by the number of times the loop executed.
The questions are:
How accurate is this measurement? I basically want to know how long
the FIRST execution of MyFunction() takes, not how long the average
takes.
Does the time executing the same function scale linearly? Does that
depend on the properties of MyFunction() (so some kind of caching
is used)? What are those properties?
Let's say you run MyFunction() 1,000,000 times in 3 seconds.
You now know:
You can at least sometimes run MyFunction() in a time less than or equal to 3μs, on similar data and with similar cache and jitter situations.
It probably runs faster than an equivalent method that takes 3.5 seconds, as long as the tests are truly equivalent. (But 3.01 is too close to be sure unless this repeats consistently).
It probably runs slower than an equivalent method that takes 2.5 seconds, as long as the tests are truly equivalent. (But 2.99 is too close to be sure unless this repeats consistently).
You do not know:
How much the time is affected on first call by jitting, static constructors, and memoisation of values that are either static or related to the particular values used.
How much the time is affected by the method still being accessible from the instruction cache (or indeed, whether it is).
How much the time is affected by the data used still being accessible from the data cache (or indeed, whether it is).
How consistent the time is subsequent to first run; is it a steady 3μs per run, or more often 1μs with some occasional large delays?
Just what portion of the time was spent on the looping rather than the running.
These five things you don't know (or four if you do a run prior to the loop to at least reduce the impact of the first one) mean you don't know an awful lot in an absolute sense.
But the three things you do know can be very useful relative to other possible approaches, or if you're clearly above or below a certain threshold (if you need to beat 2μs you're screwed, if you need to beat 500ms you're fine, if you need to consistently beat 4μs then you don't know if you have).

Does Stopwatch.Gettimestamp ever roll over? Or roll back?

In using Stopwatch.GetTimestamp() we find that if you record the return value and then continue calling it and comparing to the previous return value, it will eventually but unpredictably return a value less than the original.
Is this expected behavior?
The purpose of doing this in the production code is to have a microsecond accurate sytem time.
The technique involves calling DateTime.UtcNow and also calling Stopwatch.GetTimestamp() as originalUtcNow and originalTimestamp, respectively.
From that point forward, the application simply calls Stopwatch.GetTimestamp() and using Stopwatch.Frequency it calculates the difference from the originalTimestamp variable and then adds that difference to the originalUtcNow.
Then, Voila...an efficient and accurate microsecond DateTime.
But, we find that sometimes the Stopwatch.GetTimestamp() will return lower number.
It happens quite rarely. Our thinking is to simply "reset" when that happens and continue.
HOWEVER, it makes us doubt the accuracy of the Stopwatch.GetTimestamp() or suspect there is a bug in the .Net library.
If you can shed some light on this, please do.
FYI, based on the current timestamp value, the frequence, and the long.MaxValue it appears unlikely that it will roll over during our lifetime unless it's a hardware issue.
EDIT: We're now calculating this value "per thread" and then "clamping it" to watch for jumps between cores to reset it.
It's possible that you get the jump in time because your thread is jumping cores. See the "note" on this page: http://msdn.microsoft.com/en-us/library/ebf7z0sw.aspx
The behavior of the Stopwatch class will vary from system to system depending on hardware support.
See: http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.ishighresolution.aspx
Also, I believe the underlying equivalent win32 call (QueryPerformanceCounter) contains useful documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
I don't know exactly regarding about running backwards (which sounds like a small change backwards), but I have so far experienced three times that the value of Stopwatch.GetTimestamp() can change so enormously that it causes overflow exceptions in some further calculations of form about like this:
(Stopwatch.GetTimestamp() - ProgramStartStopwatchTimestamp) * n
where n is some large value, but small enough that if the Stopwatch weren't jumping around enormously, then the program could run years without having overflow exception. Note also that these exceptions occurred many hours after the program started, so the issue is not just that the Stopwatch ran backwards a little bit immediately after start. It just jumped to totally different range, in whatever direction.
Regarding Stopwatch rolling over, in one of the above cases it (not the difference, but Stopwatch) obtained value of something a la 0xFF4? ???? ???? ????, so it jumped to a range that was very close to rolling over. After restarting the program multiple times, this new range was still consistently in effect. If that matters anymore considering the need to handle the jumps anyway...
If it was additionally necessary to determine which core the timestamp was taken on then it probably helps to know executing core number. For this end, there are functions called GetCurrentProcessorNumber (available since Server 2003 and Vista) and GetCurrentProcessorNumberEx (available since Server 2008 R2 and Windows 7). See also this question's answers for more options (including Windows XP).
Note that core number can be changed by the scheduler any time. But when one reads the core number before reading Stopwatch timestamp, and after, and the core number remained same, then perhaps one can assume that the Stopwatch read was also performed on this core...
To specifically answer the high-level question "How often does Stopwatch.GetTimestamp() roll over?", Microsoft's answer is:
Not less than 100 years from the most recent system boot, and potentially longer based on the underlying hardware timer used. For most applications, rollover isn't a concern.

Periodical WMI Query Causes Memory Leak?

I am fairly new to the .NET programming and I am currently developing a computer health monitoring system which is in its infant stage now. I will be using C# 2010 and querying computer information by using WMI queries.
Before I could further develop the application, I have created a mini test app to test out my classes and its methods. The flow of the test app is as follow:
App startup
Input hostname, username and password
Query button clicked and the querying methods fired.
A textfield on my UI gets updated, printing out the result of the queries.
I have a class called Machine, which contains properties such as the CPU Name, and some update-able properties like the current CPU usage. In that class, I have 2 main methods, GetStaticSysInfo and GetDynamicSysInfo, where the first method queries the system info that does not change over time, and the later one queries information like CPU and memory usage. I have another method named Refresh that I use to wrap around the GetDynamicSysInfo method.
As I am using WPF for my UI, I have used the DispatcherTimer to periodically queries the machine, and prints the updated info to the textfield on the UI after the Query button has been clicked. However, I noticed that each of the time I called machine.Refresh(), the memory usage of the app increases by a bit (few hundred KBs). I can't really figure out what's wrong with the program and I would appreciate that someone could provide some advices on this.
Please let me know if you need more information, or any portions of the code.
Thanks in advance.
EDIT: I have added a GC.Collect() on the Timer_Tick method, and it seems like the memory usage still climbs but it is lowered once every few timer ticks. It is still increasing, but at a slower rate. Is this the correct way of doing it and will it impair performance in the long run?
Except for diagnosis purposes you should never call GC.Collect(). The runtime has much better algorithms for when the GC should run. Also, calling Collect() too often can result in objects being promoted to 1st or 2nd generation, which actually means they are collected more slowly after they are not used anymore, i.e. increasing your memory footprint.
If the memory goes down again (to the previous value) after manually collecting, then you have no memory leak. Since the GC doesn't run all the time, you will have increased memory in between GC runs. That is no cause for concern.

Good way of firing an event at a particular time of day?

I have an app that needs to fire off a couple of events at certain times during the day - the times are all defined by the users. I can think of a couple of ways of doing it but none of them sit too well. The timing doesn't have to be of a particularly high resolution - a minute or so each way is fine.
My ideas :
When the app starts up read all the times and start timers off that will Tick at the appropriate time
Start a timer off that'll check every minute or so for 'current events'
tia for any better solutions.
Store/index the events sorted by when they next need attention. This could be in memory or not according to how many there are, how often you make changes, etc. If all of your events fire once a day, this list is basically a circular buffer which only changes when users change their events.
Start a timer which will 'tick' at the time of the event at the head of the list. Round up to the next minute if you like.
When the timer fires, process all events which are now in the past [edit - and which haven't already been processed], re-insert them into the list if necessary (i.e. if you don't have the "circular buffer" optimisation), and set a new timer.
Obviously, when you change the set of events, or change the time for an existing event, then you may need to reset the timer to make it fire earlier. There's usually no point resetting it to fire later - you may as well just let it go off and do nothing. And if you put an upper limit of one minute on how long the timer can run (or just have a 1 minute recurring timer), then you can get within 1-minute accuracy without ever resetting. This is basically your option 2.
Arguably you should use an existing framework rather than rolling your own, but I don't know C# so I have no idea what's available. I'm generally a bit wary of the idea of setting squillions of timers, because some environments don't support that (or don't support it well). Hence this scheme, which requires only one. I don't know whether C# has any problems in that respect, but this scheme can easily be arranged to use O(1) RAM if necessary, which can't be beat.
Have a look at Quartz.Net. It is a scheduler framework (originally for Java).
This sounds like a classic case for a Windows Service. I think there is a Windows Service project type in VS2005/2008. The service coupled with a simple database and a front-end application to allow users to set the trigger times would be all you need.
If it won't change very often, Scheduled Tasks is also an option.
I've written a few programs along these lines.
I suggest #2. All you need to to is keep a list of times that events are "due" at, and every X amount of time (depending on your resolution) check your list for "now" events. You can pick up some optimization if you can guarantee the list is sorted, and that each event on the list is due exactly once. Otherwise, if you have recurring events, you have to make sure you cover your window. What I mean is, if you have an event that is due at 11:30 am, and you're checking every seconds, then it's possible that you could check at 11:29:59, and then not again until 11:31:01, due to the inprecision of the CPU time-slices. So you'll need to be sure that one of those checks (11:29 or 11:31) still picks up the 11:30 hit, and that ONLY one of them does (i.e., you don't run at both 11:29 and 11:31).
The advantage this approach has over checking only on times you know to be on your list is that allows your list to be modified by 3rd parties without your knowledge, and your event handler will continue to 'just work'.
The simplest way would likely be to use Windows scheduler.
Otherwise you need to use one of the Timer classes, calculating how long until the first event. This approach, unlike the scheduler, allows new events to be found by the running process (and, possibly, resetting the timer).
The problem with #1 is that the number of milliseconds before an event may be too large to store in the Timer's interval, and as the number of events increase, your number of timers could get unweildly.
I dont see anything wrong with #2, but I would opt for a background worker or a thread.

Categories

Resources