Inline those vector constructors

Originally posted to Shawn Hargreaves Blog on MSDN, Tuesday, January 2, 2007

Reading Chris To's article about Xbox CLR performance (see my previous post) reminded me of a subtle optimization for constructing new vector instances. Given some code like:

    DoCoolStuffWithVector(new Vector3(23, 42, -1));

You can rewrite this to avoid calling the Vector3 constructor:

    Vector3 temp = new Vector3();

temp.X = 23;
temp.Y = 42;
temp.Z = -1;

DoCoolStuffWithVector(temp);

It may not be obvious why this second version will be faster, since it also calls a Vector3 constructor, albeit the one without any arguments. The reason lies in a subtlety of how the CLR handles value types like Vector3. The default constructor for value types is special in .NET: it always exists, is always public, always just fills the structure with zeros, and you aren't allowed to override it. These restrictions make it trivial for the runtime to optimize the default constructor, so all the vector construction code in my second example can be inlined. The first example, on the other hand, contains a call to a custom Vector3 constructor which will not be inlined, and thus will be significantly slower.

This is really just a special case of a more general principle: manually inlining math computations can make things faster by avoiding method calls. The Compact Framework jitter that we use on Xbox only has limited inlining capabilities, so it can be useful to inline critical methods by hand.

WARNING!

Please ignore everything I wrote above...

Remember the #1 rule of optimization: don't do it.

Rewriting all your math code to avoid calling structure constructors will make it more complicated, error prone, and hard to maintain. This is almost certainly a bad idea.

It is good to know about this optimization in case you ever find yourself having to speed up some critical piece of code that happens thousands of times a frame, but you generally shouldn't worry about it.

Blog index   -   Back to my homepage