I’ve been profiling a method using the stopwatch class, which is sub-millisecond accurate. The method runs thousands of times, on multiple threads.
I’ve discovered that most calls (90%+) take 0.1ms, which is acceptable. Occasionally, however, I find that the method takes several orders of magnitude longer, so that the average time for the call is actually more like 3-4ms.
What could be causing this?
The method itself is run from a delegate, and is essentially an event handler.
There are not many possible execution paths, and I’ve not yet discovered a path that would be conspicuously complicated.
I’m suspecting garbage collection, but I don’t know how to detect whether it has occurred.
Finally, I am also considering whether the logging method itself is causing the problem. (The logger is basically a call to a static class + event listener that writes to the console.)
As I commented, you really should at least describe what your method does, if you’re not willing to post some code (which would be best).
That said, one way you can tell if garbage collection has occurred (from Windows):
EDIT: If you want to know if a collection occurred during a specific execution, why not do this?
SECOND EDIT: A couple of points on how to reduce garbage collections within your method:
You mentioned in a comment that your method adds the object passed in to “a big collection.” Depending on the type you use for said big collection, it may be possible to reduce garbage collections. For instance, if you use a
List<T>, then there are two possibilities:a. If you know in advance how many objects you’ll be processing, you should set the list’s capacity upon construction:
List<T> bigCollection = new List<T>(numObjects);b. If you don’t know how many objects you’ll be processing, consider using something like a
LinkedList<T>instead of aList<T>. The reason for this is that aList<T>automatically resizes itself whenever a new item is added beyond its current capacity; this results in a leftover array that (eventually) will need to be garbage collected. ALinkedList<T>does not use an array internally (it usesLinkedListNode<T>objects), so it will not result in this garbage collection.If you are creating objects within your method (i.e., somewhere in your method you have one or more lines like
Thing myThing = new Thing();), consider using a resource pool to eliminate the need for constantly constructing objects and thereby allocating more heap memory. If you need to know more about resource pooling, check out the Wikipedia article on Object Pools and the MSDN documentation on theConcurrentBag<T>class, which includes a sample implementation of anObjectPool<T>.