Archive

Archive for March, 2010

Comparing method invocation using reflection and dynamic

March 23, 2010 Leave a comment

In C# 4.0, the ‘dynamic’ keyword was added to specify that you don’t want compile time checking – all operations on an instance declared as ‘dynamic’ will be resolved at runtime. This doesn’t add any functionality that wasn’t possible before, as you could use reflection or LCG to accomplish this, but the syntax is much more natural to use and feels like the duck typing you would have in a typical dynamic language.

So what’s the cost in terms of performance? With a little benchmarking, I’ve found that there is a cost to using dynamic, but it’s certainly much faster than invoking methods using reflection. Compiled code, as you would expect, is clearly the fastest way to invoke methods. In my quick little benchmark I was able to invoke the same method about 75 times more often in a two second period using compiled code than using reflection. Compiled is still faster than dynamic – I could invoke the method about 6 times more often in code using compiled invocation than using dynamic. More surprising is the method could be invoked using dynamic about 12 times more often than using reflection.

Here are some numbers from one of my samples – I’m counting the number of times I could invoke the same method in a two second period using all three types of invocation running simultaneously to avoid environmental factors skewing results. Bigger is better – that means the method could be invoked faster.

Compiled: 159,277,840.00 method calls.
Reflection: 2,102,121.00 method calls.
Dynamic: 24,702,097.00 method calls.

What this tells me is whenever I can choose between reflection and dynamic for invoking a method, dynamic is quite likely to perform better.

Here is the source, in case you want to run a similar comparison on your own.

class Program
{
    class MyTest
    {
        public ulong SomeField;

        public void Increment()
        {
            SomeField = checked((ulong)(SomeField + 1));
        }
    }

    static void Main(string[] args)
    {
        // Do any possible setup here so we're only invoking methods during the test.
        MyTest testCompiled = new MyTest();
        MyTest testReflection = new MyTest();
        dynamic testDynamic = new MyTest();
        Type t = typeof(MyTest);
        MethodInfo incrementMethod = t.GetMethod("Increment");

        // Define the ThreadStart for method invocation using compiled, reflection, and dynamic.
        ThreadStart threadStartCompiled = new ThreadStart(() =>
            {
                while (true)
                {
                    testCompiled.Increment();
                }
            });
        ThreadStart threadStartReflection = new ThreadStart(() =>
            {
                while (true)
                {
                    incrementMethod.Invoke(testReflection, null);
                }
            });
        ThreadStart threadStartDynamic = new ThreadStart(() =>
            {
                while (true)
                {
                    testDynamic.Increment();
                }
            });

        // Setup the threads and start them.
        Thread compiledTestThread = new Thread(threadStartCompiled);
        Thread reflectionTestThread = new Thread(threadStartReflection);
        Thread dynamicTestThread = new Thread(threadStartDynamic);
        compiledTestThread.Start();
        reflectionTestThread.Start();
        dynamicTestThread.Start();

        // Wait a couple of seconds to let each thread run then abort them all.
        Thread.Sleep(2000);
        compiledTestThread.Abort();
        reflectionTestThread.Abort();
        dynamicTestThread.Abort();

        // Get the output
        Console.WriteLine("Compiled: {0:n} method calls.", testCompiled.SomeField);
        Console.WriteLine("Reflection: {0:n} method calls.", testReflection.SomeField);
        Console.WriteLine("Dynamic: {0:n} method calls.", testDynamic.SomeField);
    }
}
Categories: DLR

DLR + IBatis – ORM mappings for dynamic objects

March 16, 2010 Leave a comment

I’m a big fan of using an ORM to hide the implementation details of the database from the people writing application logic. A lot of ORM’s depend on the structure of your object to determine what SQL they emit. That can be painful sometimes because you have to design your object model and database to fit the ORM. In the case of objects with dynamic members (like those supported by IronPython, IronRuby, and now the DLR in C# 4.0) the structure of your object isn’t necessarily determined at compile time. Instead, you have a backing collection like a Dictionary for your dynamic types that will get populated at runtime with any dynamic members. That dictionary can be full of more dynamic objects. As you can imagine, trying to persist a dynamic structure like this in a not-so-dynamic relational database can be tricky, but it also gives you some nice advantages. For one thing, you can change your database structure without having to deploy any code changes.

For an example of how to create a backing collection for dynamic types for .NET 4.0, follow the documentation on http://dlr.codeplex.com to derive from DynamicObject or implement IDynamicMetaObjectProvider. For IronPython in .NET 2.0, follow the steps regarding GetBoundMember and SetMemberAfter demonstrated in IronPython in Action for examples of how to do this.

Here’s an example to illustrate. I have a base class that all my entities derive from named DynamicBase. This class has the backing collection for any dynamic members, so if I’m in IronPython or dynamic C#, I can arbitrarily add properties to any class that derives from DynamicBase. In fact, if I didn’t want to derive any classes, I could probably stop with DynamicBase.

IronPython example:

simpleDynamicPerson = DynamicBase()
simpleDynamicPerson.Name = "Bill"
simpleDynamicPerson.Title = "Boss"
simpleDynamicPerson.Height = "6ft"

anotherDynamicPerson = DynamicBase()
anotherDynamicPerson.Name = "Mike"
anotherDynamicPerson.Title = "Assistant"
anotherDynamicPerson.YearsWorking = 4

complexDynamicTeam = DynamicBase()
complexDynamicTeam.Name = "MyTeam"
complexDynamicTeam.Leader = simpleDynamicPerson
complexDynamicTeam.Assistant = anotherDynamicPerson

After running this code, I have a DynamicBase instance, and in its DynamicProperties backing collection it has two entries: “Leader”, which contains the simpleDynamicPerson instance, and “Assistant”, which contains the anotherDynamicPerson instance. The simpleDynamicPerson instance’s DynamicProperties collection has entries for “Name”, “Title” and “Height” that are populated at runtime as well.

There aren’t really any classes to map here. There are just dictionaries of dictionaries that are holding all the data. using the IBatis DataMapper, I could run a statement like this:

Mapper.Instance().Insert("StoreDynamicTeam", complexDynamicTeam)

StoreDynamicTeam needs to be the name of an statement loaded in one of the SqlMap files loaded by SqlMap.config. The ORM mapping is the only thing that needs to know about the structure of the dynamic object, or at least the fields that need to be persisted.

<insert id="StoreDynamicTeam">
BEGIN TRAN
DECLARE @teamID INT
INSERT INTO TEAM (NAME) VALUES (#DynamicProperties.Name#)
SET @teamID = SCOPE_IDENTITY()
INSERT INTO PEOPLE (NAME, TITLE, HEIGHT, YEARSWORKING, TEAM_ID) 
VALUES (#Leader.DynamicProperties.Name#, 
#Leader.DynamicProperties.Title#, 
#Leader.DynamicProperties.Height#, 
#Leader.DynamicProperties.YearsWorking#,
@teamID)
INSERT INTO PEOPLE (NAME, TITLE, HEIGHT, YEARSWORKING, TEAM_ID) 
VALUES (#Assistant.DynamicProperties.Name#, 
#Assistant.DynamicProperties.Title#, 
#Assistant.DynamicProperties.Height#, 
#Assistant.DynamicProperties.YearsWorking#,
@teamID)
COMMIT
</insert>

Getting that data back out isn’t much more difficult.

dynamicPeople = Mapper.Instance().QueryForList("GetDynamicTeam", teamID)

My statement and the resultMap need to deal with the dynamic parameters:

<select id="GetDynamicTeam" parameterClass="int" resultMap="DynamicTeamResult">
SELECT p.NAME AS PERON_NAME, 
p.TITLE AS TITLE, 
p.HEIGHT AS HEIGHT, 
p.YEARSWORKING AS YEARSWORKING
FROM TEAM t
INNER JOIN PEOPLE p ON p.TEAM_ID = t.TEAM_ID
WHERE t.TEAM_ID = #value#
</select>

<resultMap id="DynamicPersonResult" class="MyClassLib.DynamicBase,MyClassLib">
   <result property="DynamicProperties" resultMapping="DynamicPropertiesResult" />
</resultMap>

<resultMap id="DynamicPropertiesResult" class="System.Collections.Generic.Dictionary`2[[System.String,mscorlib], [System.Object,mscorlib]], mscorlib">
   <result property="Name" column="PERSON_NAME" />
   <result property="Title" column="TITLE" />
   <result property="Height" column="HEIGHT" />
   <result property="YearsWorking" column="YEARSWORKING" />
</resultMap>

When you execute it, dynamicPeople will be a collection of DynamicBase objects with their dynamic properties populated. What’s very cool about these properties being dynamic is that you could change your query in your mapping file to add some new fields from some other table, update the resultMap to use those fields, and they’ll show up on your dynamic object.

Categories: DLR Tags: , , ,