Posts for December 2006

Reflection vs. dynamic code generation

For the code I'm writing for my job I need to set a lot of properties based on values read from external files. Not only the values are dynamic, so are the property names. To prevent this turning into a giant switch statement that needs to be updated every time I add a property, I wanted to use reflection.

Of course, I've often heard that reflection is slow, and this property setting operation will be done a lot. But, I'm also a big proponent of preventing premature optimization, so I decided to build a simple test, where I pitted reflection against using a dynamically generated method, using .Net 2.0's supercool DynamicMethod class which allows for light-weight code generation. Below is the code I used for this test:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;
using System.Diagnostics;

namespace DynamicMethodTest
{
    class Foo
    {
        private string _bar;

        public string Bar
        {
            get { return _bar; }
            set { _bar = value; }
        }
    
    }

    class Program
    {
        delegate void TestDelegate(Foo arg);

        static void Main(string[] args)
        {
            TestDelegate test = CreateMethod();
            Stopwatch s = new Stopwatch();
            Foo f = new Foo();
            s.Start();
            for( int x = 0; x < 1000000; ++x )
                test(f);
            s.Stop();
            Console.WriteLine("Dynamic method: {0}", s.Elapsed);

            s.Reset();
            Type t = f.GetType();
            PropertyInfo info = t.GetProperty("Bar");
            s.Start();
            for( int x = 0; x < 1000000; ++x )
            {
                info.SetValue(f, "Hello, World!", null);
            }
            s.Stop();
            Console.WriteLine("Reflection: {0}", s.Elapsed);


            Console.ReadKey();
        }

        static TestDelegate CreateMethod()
        {
            Type[] args = new Type[] { typeof(Foo) };
            DynamicMethod method = new DynamicMethod("Test", null, args, typeof(Program));
            ILGenerator gen = method.GetILGenerator();
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldstr, "Hello, World!");
            MethodInfo m = typeof(Foo).GetProperty("Bar").GetSetMethod();
            gen.EmitCall(OpCodes.Call, m, null);
            gen.Emit(OpCodes.Ret);

            return (TestDelegate)method.CreateDelegate(typeof(TestDelegate));
        }
    }
}

And this is the result:
Dynamic method: 00:00:00.0326159
Reflection: 00:00:05.8752216

As you can see, reflection is not just slower, it's orders of magnitude slower! This result far exceeds the speed difference I was expecting. I tried to find something wrong with the benchmark, something that would skew the result, but I cannot find anything at first glance (if anyone sees a problem please let me know).

So it would appear that if you have to do a lot of reflection, taking the time to implement dynamic code generation can really pay off.

It's important not to underestimate the power of DynamicMethod. In my case the configuration file containing the properties to set can change without the application restarting; this means that I will need to recreate the dynamic methods and discard those I don't need anymore. And that's precisely the biggest advantage to DynamicMethod; it's discardable. In .Net 1.1, if you wanted dynamic code generation, you had to generate a complete in-memory assembly, and if you're familiar with the CLR you'll know that assemblies (generated or otherwise) cannot be unloaded. That would mean that to prevent a memory leak I would have to place the generated assembly in a separate AppDomain (which you can unload, also unloading all the assemblies contained in it), with all the hassle and performance implications that entails. Thanks to DynamicMethod, none of that is necessary.

Categories: Programming
Posted on: 2006-12-20 23:56 UTC. Show comments (1)

MSDN article on BHOs

I've just become aware that there's a new article on MSDN that provides a step-by-step guide on building a Browser Helper Object for Internet Explorer. Since I know first hand how hard developing IE extensions can be (although Find As You Type is primarily a toolbar, it also uses a BHO to capture the CTRL-F keypress) it's good to see that MS is at least improving the documentation that is out there.

The article uses ATL, which I personally didn't use. Not that I have anything against ATL; it's just that I'm familiar with COM and prefer to have the least amount of auto-generated code possible. But if you're a fresh C++ programmer who's perhaps transitioning from the .Net world who wants to try his/her hands at developing an IE extension, ATL is an excellent way to hide all the tricky bits of doing COM.

Categories: Programming
Posted on: 2006-12-17 23:24 UTC. Show comments (0)

C9 International Avatar Creator update

In honour of the upcoming holiday season I decided to resurrect Jamie's Christmas avatars. I also took the opportunity to release a small update to the C9IAC itself (as well as the accompanying template editor).

The biggest improvements are in Vista compatibility (it now uses Segoe UI for the UI font, and it will use the Vista style common file dialogs) and high-DPI compatibility. But there's also other stuff, including some UI updates, a change in the default font for avatar text to Calibri, and some other small stuff.

C9 International Avatar Creator

Go check it out!

Categories: Software
Posted on: 2006-12-15 16:01 UTC. Show comments (0)

Day 2: XML

Well, I'm happy to report Floris saw the light so DIAL will get an XML interface as well. Which means I can gladly forget about the whole YAML business. It also means there are no obstacles to using .Net, so I'll be spending the next three months working with the tools I like best. :)

Now might be a good time to give an overview of what I'm doing. As I said before, I'm working on a GUI for the DIAL genomics database. DIAL is a database that biologists can use for storing and processing DNA microarray data. As I said yesterday, there are currently four ways to interact with the server: perl, command-line, HTML, and YAML (and soon XML will be added to that). The current web interface is unfortunately not very user friendly so it's my job to make a better, wizard-based one.

The difficulty lies in the amount of flexibility it must have and the constraints I must work under. The first constraint is that DIAL is the way it is and besides small things they're not going to change it for me. Additionally, as new functionality gets added to DIAL, it must be as easy as possible to adapt my GUI to it. Using the soon-to-be XML (or the current YAML) interface I can basically "replay" the regular web interface. The data returned by the server is simply a list of all possible options that can be used by the user. The web interface simply displays those options as HTML form controls, where the YAML/XML interface just gives you a list of options. As you send input to the server to set different options, more options can become available. And sometimes there will be data included as well.

The options I get from the server are grouped, and I can discern the grouping based on the names of the options. For instance, all names starting with "Client::form_login" have to do with logging in. It is on this grouping that I plan to base the wizard. At its simplest, a group of options will become one wizard page in my GUI.

Of course, that's not all there's to it. There's more information needed that I won't get from the server because it's not in the currently existing web UI. For example, I divide the options into pages so it'd be nice if every page has a clear and concise title. Since the current UI doesn't use these pages, there's no titles. It can also be the case that a little more thorough restructuring of the options is necessary to make it user friendly; maybe we want to split a group of options into two pages, or combine two groups into one page, or change the order of the pages or the individual options on a page.

To allow for this, I plan to use a two-fold approach. First I will use additional data that will be combined with the data returned by the server that will allow me to define things like titles, page orders, and other transformations that might be needed. It will be possible for the GUI to use more than one set of this kind of "modifier" data; they will be loaded in order with each having the ability to override the settings from the last. This allows for e.g. user-specific settings that complement or override global settings. And second, I will make it possible to specify a custom server control to handle a specific group of options. That way, whenever something needs to be done that falls outside the regular options available for my GUI, it can still be done.

Of course, this is just my preliminary idea. Tomorrow I'm having a meeting which will involve getting some feedback from real users on the system as it currently is, and next week I will join a demonstration of the system at the VUMC in Amsterdam, and I'm sure that will influence the design.

Categories: University
Posted on: 2006-12-05 16:59 UTC. Show comments (0)

Did someone say WPF/E?

I'm not usually one to rehash news stories on my blog, but some things are cool enough to make an exception. WPF/E is one of those things.

I for one am wondering how this "Flash-killer" will take on. On the one hand I'm sure it has many compelling features (while I haven't looked very deeply into it, if it's even remotely like the real WPF it has to be better than Flash ActionScript; not that that's hard, though), but on the other hand Flash has an extremely strong foothold in the "rich media on the web" arena. And although alternative browsers are supported by WPF/E, people who use those alternate browsers often do so for reasons that would make it unlikely for them to accept a plugin from MS.

I don't claim to be a psychic, so just like the rest of you all I can do it wait to see how it pans out. But I'm sure it's going to be interesting.

Categories: General computing
Posted on: 2006-12-04 22:34 UTC. Show comments (0)

Latest posts

Categories

Archive

Syndication

RSS Subscribe

;