Profiling A C# Application with the Stand-Alone Profiler

Here’s the scoop. I wanted to profile my application to show someone how we could get the best “bang for our buck” on a single hardware upgrade. Did I need more memory or CPU? I expected, in the course of collecting metrics, to find some slower code snippets to improve software side. It can be sped up a little bit, but the fact of the matter is that the sheer volume of data has increased to a tipping point the hardware simply could not handle in the same time frame. Also, I wanted like to start doing this on a more regular cadence, so I would need any help I can get to speed up the process. You would think that Visual Studio 2008 would have something built in for C#. Well, it does if you shell out the extra money for the Team Edition. I have Professional. I am thusly screwed, right?

Wrong. For some reason they offer the Performance Tools from the Team Suite as a free download online. Check it out! How nice, Microsoft! The only draw back is that you will be doing this through the command line. (Even then, for some that is a pro and not a con.) My program is a command line utility, so it did not really change my method, but it is something to note as a draw back for the less command line literate. So I looked for a tutorial to get me on my way and I found everything I ever needed. Sort of. A little bit.

I spent way too much time staring at a blue screen. It was horrendous to behold. All I was trying to do is profile my C# application to gather some metrics for something I already know. The computer needed a memory upgrade. Before you even begin, see if you need this patch: http://blogs.msdn.com/b/chrissc/archive/2009/02/24/patch-released-to-fix-sampling-on-intel-core-i7-processors.aspx. Otherwise you will blue screen constantly and think you are doing something wrong. Trust me, it is a huge waste of time if you have an i7 processor and don’t download this patch.

To get us started, here is the article of reference I used: http://msdn.microsoft.com/en-us/library/aa985628.aspx. This was probably the best source of information. I will be duplicating some of the information here in walking through how to profile a C# application.

Let’s begin. Build your binaries in Release! Building in Debug is a waste of time as it does not perform quite the same. Add the location of the VSPerf tools to your PATH. Again, build Release and then fire up the command line. For me, this was located in “C:\Program Files (x86)\Microsoft Visual Studio 9.0\Team Tools” and if you have Visual Studio 2008, that’s where it should be for you. Translate to the proper Visual Studio install and OS for your machine.

Now you have a choice to make: Sampling or Instrumentation. If sampling, you just need to turn sampling on globally with the following command:

VSPerfCLREnv /sampleon

If you are using instrumentation, you will have to do slightly more. Turn on instrumentation globally:

VSPerfCLREnv /traceon

For all of the dll and exe files that you will be profiling, (hint: do this for dependencies) you will need to run the following commands to allow instrumentation.

VSInstr ProgramOrDll.exe

Now you’re ready to collect some data. I hope you have a simple, repeatable test planned. This is critical to identifying performance issues, especially if you plan on fixing them. Always have a repeatable test and run it multiple times to ensure you get correct data. Run your program from the command line with Performance Monitor by using the following command:

VsPerfCmd /start:sample /output:Report.vsp /launch:YourProgram.exe

When you’re done with sampling, you must turn it off with the following command. (Instrumentation will end when your program ends.)

VSPerfCmd /shutdown

Now you’ve got a beautiful vsp sitting on your hard-drive! This is the raw performance data. Now you need to change it into a consumable format because of our lowly Visual Studio version. Team Edition opens these bad boys. We are going to use more primitive tools. Microsoft, and I, recommend creating a folder at this point to help stay organized. Run this command to create a bunch of csv files:

VSPerfReport PeopleTraxReport.vsp /output:path\filename /summary:all

Now, don’t forget to restore your environment!

VSPerfCLREnv /sampleoff

These csv files are all different types of profiling information. You can tell what they are by the extension. There are functions, threads, modules, etc; My recommendations? If you’re looking for hotspots, use the _functions file. Application Exclusive Time is a great column to sort. If you’re trying to find a dead-lock or places of I/O wait try the _threads file. Otherwise, enjoy!

Run Time Type Checking In Objective-C

There I was programming away, implementing a factory in Objective-C. My C++ instincts told me I would either need to create an enumeration, a template, or some sort of Factory inheritance chain. My C# intuition pointed me in the direction of Reflection. Reflection was pretty slick, so I opted to look down that path. You know what? There was a bright light at the end of that tunnel.

Now, what I found wasn’t exactly reflection, more like run time type checking, but it was certainly a useful tool to accomplish what I needed to do. What’s that magic?

1
[SomeClass class];
[SomeClass class];

That’s right, there is actually an object called Class. Every single object implicitly has a member of type Class, the isa pointer, which you can get with the “class” message. This member tells you to what type your object points. You may have noticed this while debugging in XCode. Every time you mouse over a variable you get that lovely isa pointer. You probably thought it was obvious and totally annoying if you came from Visual Studio. Class is a strong type of which you can declare instances, pass to functions, and anything else you can do with a class. You can use this for numerous things, the most obvious among them being run-time type checking. Is my BaseVehicle object ACTUALLY a Car or is it a Plane? Grab that class and compare like so:

1
2
3
4
5
Class realClass = [someVehiclePointer class];
if ([realClass isKindOfClass:[Car class]])
{
// Do something specific to Cars.
}
Class realClass = [someVehiclePointer class];
if ([realClass isKindOfClass:[Car class]])
{
// Do something specific to Cars.
}

Maybe, you want to know more than whether you’re a Car. You have a Sedan or a SportsCar class derived from Car and you even have Civic, Camry, Charger, and Lamborghini classes derived from those types. Maybe you only want SportsCar derived classes.

1
2
3
4
if ([realClass isSubclassOfClass:[SportsCar class]])
{
// Get ready for the races!
}
if ([realClass isSubclassOfClass:[SportsCar class]])
{
// Get ready for the races!
}

Now, what if you wanted to test for exact matches only? What if you wanted to put your foot down and make sure that there is no inheritance masquerading, and that your object MUST be a Lamborghini in order to respond to the OpenButterflyDoors message. There is a message for that as well!

1
2
3
4
if ([realClass isMemberOfClass:[Lamborghini class]])
{
[someVehiclePointer OpenButterflyDoors];
}
if ([realClass isMemberOfClass:[Lamborghini class]])
{
[someVehiclePointer OpenButterflyDoors];
}

Finally, another trick you can do with Class, is use an instance of Class as a type. (Huh?) Meaning whatever you can do by typing the actual class name, it is possible to do with an instance of Class. (Well, except forward declaration, I think.) For example, if I had a VehicleFactory, I could implement a method in the following way:

1
2
3
4
5
6
7
8
9
10
11
12
- (Vehicle*) createGameObjectOfClass:(Class)type Error:(NSError**)error
{
Vehicle* result = nil;
 
if ([type isSubclassOfClass:[Vehicle class]])
{
result = [[type alloc] init];
[m_objects addObject:result];
}
 
return result;
}
- (Vehicle*) createGameObjectOfClass:(Class)type Error:(NSError**)error
{
Vehicle* result = nil;
if ([type isSubclassOfClass:[Vehicle class]])
{
result = [[type alloc] init];
[m_objects addObject:result];
}
return result;
}

Hello, Factory! Hello, decoupling! Hello, Class! But wait, there’s more! Is it necessary to check if you subclass something? Maybe my factory follows a different contract. By convention, people usually think that you need to be of a certain subclass to have any given collection of functions. Not true. You don’t have to derive from a Car in order to accelerate and decelerate. In fact, a Person does the same thing. If I only care about subclassing because I don’t want to add objects that can’t respond to that message there is a more accurate check!

1
2
3
4
if ([vehicle respondsToSelector:@selector(accelerate)])
{
// Make the thing go vroom!
}
if ([vehicle respondsToSelector:@selector(accelerate)])
{
// Make the thing go vroom!
}

At this point, you may be looking at all of this and thinking it is a bit of black magic. It must have a harsh performance penalty. It seems you would be disappointed. You see, Objective-C sends messages using a similar methodology all the time. You check the isa pointer on a class to see whether or not a selector (method, message) is handled by the class. If it is not, you check the parent class, rinse, repeat. Theoretically, you incur the same cost as calling a function (sending a message.) The only gotcha there is that over time, messages that are commonly called get put into a cache and don’t incur the walking of the inheritance chain. (See link.) If you want faster performance than that… well, you could turn to these articles and start implementing your own obj_msgSend function. Personally, I prefer readability. I prefer clarity and reduced maintenance costs. I prefer simply sending messages by using the bracket notation and the simple isKindOfClass message.

Thoughts? Comments? Clever uses for the isa pointer? Drop a comment!

See you, Space Cowboy.

Welcome to the New Chad++

“Out with the old, in with the new,” they say. (Even if we’re not quite sure who they are.) You’ll notice that the old is currently gone and that there’s only this in it’s place.

It’s a whole new year, baby. Welcome to my fancy, new blog. I decided to move hosts to WP Engine, a dedicated WordPress host who will serve my pages 4.7x faster. (Yes, that’s a real, measured metric.) As a part of the move, I have decided to do some major house-keeping. I am going to edit the heck out of the previous content I had and re-post it eventually along with plenty of fresh stuff.

So welcome. If I could pretend this was a website from the earlier 90′s for a moment:

https://www.google.com/search?q=Pardon+My+Dust

There are exciting things to come. We just launched Star Wars: The Old Republic. I have news I cannot share, yet. I just got a new toy and I want to get programming. Join me, won’t you? Until next time…

 

See you, Space Cowboy.


Hosting WordPress