The Code Slinger

November 27, 2007

Dynamic Object Instantiation: Performance

Filed under: .NET,C# — Pete @ 2:09 am
Tags:

Sometimes we write code that we know has performance issues, making a mental note to “come back” and really refactor it later to get the most bang for the buck. We do this because of deadlines, because we can’t figure out any other way at the moment it needs to be done, or we are simply lazy sometimes and tend to implement code in a manner we are familiar with and understand.

While I don’t necessarily think this is always bad as some purists might, I do think that we should always make it a point to eventually revisit these performance nightmares, as often we learn more by diving into alternative ways to solve old problems than by solving new problems.

One particular glaring example for me has always been the use of Activator.CreateInstance. It’s soooo easy to use and seems to run fairly fast, assuming one isn’t creating a billion objects. Most business applications don’t come anywhere near requiring this type of performance, so I’ve always just taken the easy way out. However I got a bug in pants today to revisit this reflection nightmare and see if I couldn’t come up with a way to speed it up or find an alternative.

Here’s what my normal code would look like:

 

    public static class Proxy<T>

    {

        public static T CreateNew(int id)

        {

            return (T)Activator.CreateInstance(typeof(T), new object[] { id });

        }

    }

So when we use this, we’d simply say something like TestClass tc = Proxy<TestClass>.CreateNew(10); And that’s all fine and dandy, except the performance for large numbers of objects can be terribly slow (how slow?…we’ll see in a bit).

So my first idea was to use my old trusty friend, Mr. Cache. I figured I could cache the ConstructorInfo object representing the constructor for each various type that my generic Proxy<T> class might call. Then just reuse that same ConstructorInfo object by invoking it directly when new instances needed to be created of that type. So this is what I got:

  

    public static class Proxy<T>

    {

        static Dictionary<Type, ConstructorInfo> d = new Dictionary<Type, ConstructorInfo>();


        public static T CreateNew(int id)

        {

            Type t = typeof(T);

            if(!d.ContainsKey(t))

                d.Add(t, t.GetConstructor(new Type[] { typeof(int) });

            return (T)d[t].Invoke(new object[] { id });

        }

    }

Not too bad. The only thing I don’t like is that we have to use the ugly “Invoke” syntax and object based parameters. There’s no compile time checking to make sure the right constructor is being called, or has the proper parameters for that matter. However I suspect this is much faster than the Activator.CreateInstance method, so we’re making progress.

However, one of the reasons that I even started examining how to speed up this type of code was a sort of obscure sentence that I read in some Microsoft literature concerning .NET delegates. It said basically that pure delegate invocation in .NET is almost as fast as directly calling the method in the first place. That got me thinking about the creation of new objects in the sense that really we’re just calling a special method, i.e. the constructor. If we could figure out a way to create a persistent delegate that points to our type’s constructor, and call that when we need a new instance, that would surely be as close to the direct method call as possible right? Let’s find out.

 

 

    public static class Proxy<T>

    {

        public delegate T GenericDel<T>(int id);

        static Dictionary<Type, GenericDel<T>> dict = new Dictionary<Type, GenericDel<T>>();

        public static T CreateNew(int id)

        {

            Type t = typeof(T);

            if (!dict.ContainsKey(t))

            {

                var dm = new DynamicMethod("", t, new Type[] { typeof(int) }, t);

                ILGenerator il = dm.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);

                il.Emit(OpCodes.Newobj, t.GetConstructor(new Type[] { typeof(int) }));

                il.Emit(OpCodes.Ret);

                var d = (GenericDel<T>)dm.CreateDelegate(typeof(GenericDel<T>));

                dict.Add(t, d);

            }

            return dict[t](id);

        }

    }

So we have a few new things here. First is a generic delegate GenericDel<T>. This defines the signature of the method we will call (i.e. our constructor) for any type T. Obviously in a real world situation T would be defined further guaranteeing such a constructor exists. But for this test leaving this off is fine.

Next we have a static dictionary which holds the delegate with it’s key which is a Type object. Now we simply create a DynamicMethod that matches our constructor, emit the IL code that is necessary to call the constructor method successfully (push the first param of the dynamic method onto the caller’s eval stack, create the new object, then return from the method invocation placing the return value on the callee’s eval stack). Then to wrap things up we generate a delegate of this method and add it to the dictionary.

Now notice the return statement for any object of a particular type once the DynamicMethod has been created….it works just like any other method or delegate call, intellisense works, and there is compile time checking for the proper parameterization of the constructor. Plus, since we’re caching the delegate, and not creating it each time a new object is instantiated dynamically, we don’t incur the cost of creating it more than once per application lifecycle.

Now….for the results:

dyn_obj_creation_output

The test for the output shown was done on my laptop, which is a Dell 9400 with an Intel Core Duo T7200 @ 2.00 GHz with 2 Gb of RAM. This particular run was churning through 100 million objects of a class called TestClass (which simply holds an ID value) for each type of invocation we covered in this article. I did not run the Cache version with this test, as it was so slow that 100 million objects would take a very very long time. The fastest two were obviously the Direct invocation and the DynamicMethod & Delegate version, which we covered last.

In this example I took the code out for the DynamicMethod creation to get a true sense of how close delegate invocation is compared to raw calls. The raw calls average around 65 nanoseconds per object instantiation. The DynamicMethod & Delegate version averages just over 76 nanoseconds. Not too shabby at all I’d say!

For those interested, I’ve included the test code I used to generate this demonstration. It is obviously a test only, so please feel free to modify it and test other things that I did not.

Til next time…keep on slangin!

Part II 


 Example Project Download

Advertisements

12 Comments »

  1. Cool stuff. Have you plan to refine this as you described and use it in production? I am interested as I am working on a calculation engine and the rapid creation of a high number of objects is of interest.

    Good post.

    Comment by ActiveEngine Sensei — November 27, 2007 @ 7:24 pm | Reply

  2. That’s a very interesting technique!

    Comment by Milan Negovan — November 28, 2007 @ 8:09 am | Reply

  3. Sensei,
    I actually have taken this and adapted it into a custom DAL I wrote that used to use the Activator.CreateInstance method to create each object. I have noticed some visible application performance, however the big thing I’ve noticed is the decreased CPU usage with moderate user load, which I believe will enable me to get more concurrent users on each server (reducing hardware requirements potentially). It is out in our staging environment right now under heavy test……if all goes well, it will get released to prod in the next few weeks.

    Comment by thecodeslinger — November 28, 2007 @ 9:37 am | Reply

  4. […] Filed under: .NET, C#, MSIL — thecodeslinger @ 8:50 pm After implementing the findings from Part I I got to thinking about how to utilize the same basic concept for creating, caching and calling […]

    Pingback by Dynamic Object Instantiation: Performance (Part II) « The Code Slinger — December 3, 2007 @ 8:50 pm | Reply

  5. […] Dynamic Object Instantiation Part I Dynamic Object Instantiation Part II […]

    Pingback by New Blood in Deadwood « ActiveEngine — December 4, 2007 @ 6:42 am | Reply

  6. VERY* impressive! Thank you for sharing this.

    Comment by Aizikovich Evgeni — December 22, 2007 @ 10:12 am | Reply

  7. Super! I was wondering this very thing and this really clears it up, along with http://aspnetresources.com/blog/dynamic_insstantiation_perf.aspx (to demonstrate how SLOW the reflection options are) which you posted on.

    I was basically wondering if I could “get away with” using reflection which would make it easier, but the performance is just SO much worse I don’t want to risk it. Not that I’ll be creating 100 million objects, but still. 😉

    Now on to part II…

    Comment by Logan — April 16, 2008 @ 5:36 pm | Reply

  8. Nice article and clearly explaned.

    Thanks.

    Comment by majkinetor — October 13, 2008 @ 6:25 am | Reply

  9. I would like to use this as we are developing web pages that load and fill controls dynamically. The database can suppy the names of the controls to load, or the names and types, as strings, of the Singleton classes, that will be used to fill them, as in the case of drop downs.

    It seems that you cannot call your instantiation method, or other generic methods, without knowing the Type at design time.

    I have tried to hold a collection of the controls or class types that will be needed for each control, but then I am faced with SomeMethod which throws its own error about a variable was found instead of the class or namespace that was expected.

    I am currently thinking of having separate factories for each type of dictionary class that will be needed, and then calling your instantiation method with the known types. But was hoping for a more generic solution.

    Any suggestions?

    Thanks for any help.

    Comment by Walter — January 26, 2009 @ 3:32 pm | Reply

  10. Hello mates, fastidious article and pleasant arguments commented
    at this place, I am truly enjoying by these.

    Comment by fusevision seo — April 22, 2013 @ 3:36 am | Reply

  11. I absolutely love your blog.. Great colors & theme.
    Did you develop this site yourself? Please reply back as
    I’m attempting to create my own personal site and would like to find out where you got this from or just what the theme is called. Thank you!

    Comment by Adhocspace Business Space Matching Site — July 9, 2013 @ 2:50 pm | Reply

  12. What’s Taking place i’m new to this, I stumbled
    upon this I’ve found It absolutely useful and it has helped me out loads. I’m hoping to
    give a contribution & assist other users like its helped me.
    Good job.

    Comment by office space for rent — July 23, 2013 @ 7:23 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: