Slower than Reflection; meet StackTrace

I was entertaining the idea of contextual components that would act differently depending on who called them. System.Diagnostics.StackTrace is the class that allows you to traverse the call stack, and see who called your method. There’s one catch though – it is painfully slow. And by painfully, I mean this:

StackTrace

Those two methods are by no means comparable in regard of what they’re doing. They are mere examples of simple tasks: one involving Reflection, and one involving StackTrace. The fact that the difference in performance is nearly two orders of magnitude, should make you think twice before you go down the StackTrace path. Especially considering the fact, that you can’t really cache it.

Technorati Tags: , ,

Comments

Pawel Pabich says:

2 orders of magnitued would be 700, a bit creative book-keeping :). It looks like you are comparing apples to oranges. Reflection is used to retrieve the method in a static way whereas StackTrace is dynamic by its nature.

@Pawel
7 vs 266 is more or less two orders of magnitude: http://en.wikipedia.org/wiki/Order_of_magnitude

I guess you didn’t catch my intention with this post, I didn’t want to compare stacktrace gathering to reflection, as it is, as you said – comparing apples to oranges.
I only wanted to show performance penalty for that, and compare it to what people consider already a veery slow operation – Reflection.

Part of the poor performance could be that you’re walking the entire stack when all you need is one frame. Not that your stack is particularly deep in that example…

I wonder if it would be significantly faster by using the more direct StackFrame constructor:

new StackFrame(1)

Thomas Skyldahl says:

If you try performing the same where you create the StackTrace outside the method, static or whatever you like and do the same again I think you will see some better numbers.

Troy says:

The contents of the stack trace are determined at the time of instantiation, not where it is referenced. There is no (obvious) way to refresh the stack trace once it is instantiated. I tried having a stacktrace member variable at the class level, and referencing it from my methods (hoping, like you, to get updated trace info without the overhead of re-instantiating the stack trace object), but it always shows the stack trace from the time of object creation.

Jorge Silva says:

Some while ago I viewed the StackTrace class and imediatelly built up a logging framework around it, something that would Really record everything I do in code, not just for recording purposes, but also for replay purposes. Of course it took me several weeks to accomplish it.

Well, as a good coder I suppose I am, I first designed, then built, then tested. Well, testing should have been the first thing to do because it’s amazing how slow this class can be. I mean, Slow is redefined here as AlmostStopped. And Microsoft seems to have no plans on building up the performance.

So, I guess that was a good idea, indeed. A good idea totally trashed!