This blog has moved, Update your bookmarks.

Stefan Rusek | LINQ Expressions as Fast Reflection Invoke

LINQ Expressions as Fast Reflection Invoke

October 26, 2008 @ 3:42 pm

Lately, I’ve been working on a side project that generates a lot of LINQ expression trees (LET). They provide a fun new way to dynamically generate executable code at runtime. Dynamic code generation has been around for a long time, and .NET has had dynamic assembly generation since the very beginning. The original mechanism, System.Reflection.Emit can be a lot of work to generate something small. (Not to mention it has little IL validation, so it will happily generate broken code that crashes your program with all kinds of strange exceptions.) Yesterday, I asked myself why not use expression trees instead of reflection for dynamic invocation. It immediately struck me as a wonderful idea.

The reason LETs are so great is that they compile down to real IL, and then get JITed, so they run at native speeds. Using reflection to dynamically invoke a method is far slower. Here is the code to create generic accessor delegates using both LET and reflection:

static Func<T, U> CreateWithLET<T, U>(string property)
{
    var t = Expression.Parameter(typeof(T), “t”);
    var prop = Expression.Property(t, property);
    return (Func<T, U>)Expression.Lambda(prop, t).Compile();
}

static Func<T, U> CreateWithReflectionFast<T, U>(string property)
{
    Type type = typeof(T);
    object[] args = new object[0];
    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
    PropertyInfo propinfo = type.GetProperty(property, flags);
    MethodInfo getter = propinfo.GetGetMethod();
    return (T t) => (U)getter.Invoke(t, args);
}

static Func<T, U> CreateWithReflectionSlow<T, U>(string property)
{
    return (T t) => (U)typeof(T).InvokeMember(property,
        BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public,
        null, t, new object[0]);
}

I have focused on making the first two methods short, readable, and as efficient as possible. Both cases do as much work as possible in the create method. The third is to show that the reflection version can be written in one line, but if you plan to use it repeatedly, it will be much slower than the multi-line version above. This is a really simple yet very powerful example. It would be trivial to change this example to call a method and pass in arguments

I wrote four benchmarks. Each benchmark runs in a loop, the cost of the loop is subtracted from the total, and each delegate is given 100 warm up iterations to ignore the cost of just in time compilation. (I’ve included the benchmark driver at the bottom of this article.) The first benchmark calculates the amount of time it takes to create the delegates we are testing. The second benchmark times 100,000 iterations accessing an int property. The third benchmark times 100,000 iterations accessing a string property. The fourth benchmark times 100,000 iterations accessing two int properties and adding the results from within the generated LET .

I added the int tests because I thought the reflection tests would be adversely effected by needing to box and unbox the value of the property. In reality, reflection is so much slower that boxing accounts for about 2% of execution time.

Create Delegate Access int
(100,000 times)
Access string
(100,000 times)
Access 2 ints
(100,000 times)
With LETs 2.338ms 0.45ms 0.46ms 0.53ms
With Fast Reflection 0.46micros 474ms 462ms 976ms
With Slow Reflection 0.05micros 988ms 862ms 1751ms

I was surprised at just how much faster the LETs were than reflection. I expected them to be faster but they are about 1,000 times faster than the than fast reflection. The slow reflection approach takes twice as long as the fast reflection. I should point out that if you are only going to call the method once then reflection is still faster, but if you are going to use it in a loop, then LETs will generally win out. Another case were it makes sense to use the LET approach is when you want to precreate the accessor delegate and cache it so you can run it later when you need the speed.

Most of the 2ms it takes to compile the lambda expression is spent creating a dynamic assembly and various other things. So if you need to access multiple members dynamically and then do an operation on them, then LETs become even more appealing. It does not take significantly longer to to generate a lambda that access two properties than it does to access one. As you can see in the benchmark, a more complicated LET only takes a small amount of extra time, while using reflection is takes twice as long. This means that if you need to do some more complicated reflection, then LETs become more and more appealing.

Below is the benchmark function I wrote:

static void Run<T, U>(T t, Func<T, U> a)
{
    // time loop
    var sw1 = Stopwatch.StartNew();
    int j;
    for (int i = 0; i < 100000; i++)
        j = i;
    sw1.Stop();

    // warm up
    for (int i = 0; i < 100; i++)
        a(t);

    // run test
    var sw2 = Stopwatch.StartNew();
    for (int i = 0; i < 100000; i++)
        a(t);
    sw2.Stop();
    Console.WriteLine(sw2.Elapsed - sw1.Elapsed);
}

Stefan Rusek | The 3 cast operators in C#

The 3 cast operators in C#

October 22, 2008 @ 8:04 am

There are three cast operators in C#. The first is the traditional cast operator that uses parentheses, the second is the “is” operator, and the third is the “as” operator.

Normal Casts

This operator uses the same syntax as the original C cast operator. The key thing is that it always returns an instance of the type you are requesting. If it can’t do the cast, then it throws an exception. The majority of the time this is the desired behavior, because you want an exception earlier in your code rather than later.

object o = “hi”;

string s = (string)o; // works

double d = (double)o; // throws an exception since it can’t return a double

The “is” operator

This operator doesn’t actually return the result of the cast. It simply returns whether the cast would have succeeded. This is handy when you want to ask if an object is an instance of a type, but you don’t actually need an instance of the type. This operator is pretty useful, but it turns out that most of the time you really want to use the “as” operator, however, there are times when you really do want the is operator.

if (o is string)  lblType.Text = “o is a string”;

if (o is double)  lblType.Text = “o is a double”;

Some people might disagree that the “is” operator is a cast. They might say that it is a runtime type check or something like that, but type references in .net have the same value before and after a cast. This means that the normal cast simply does a runtime type check and if the result if false, then it throws an exception.

The “as” operator

The “as” operator returns an instance of the type request, but if it cannot do the cast, it will return null. This operator is handy for fixing the most common pattern for using the “is” operator. Since the “is” operator is a cast in disguise, when people use the “is” operator they usually end up doing two casts, and the “as” operator allows you to avoid the double cast.

if (o is string) {

   string s = (string)o; // wrong because we are doing 2 casts

   lblO.Text = s;

}

string s = o as string;

if (s != null) lblO.Text = s;

In C# v2, the as operator becomes even nicer with the null coalescing, because you can easily replace a non-matching cast with a desirable default.

lbl0.Text = o as string ?? “No value given”;

Common Mistakes

When I first learned about the “as” operator, I used it a bunch, and I ended up with code like this:

Converter c = x as Converter;

c.DoConversion();

The problem with the above code is that if the cast fails, then the second line throws an exception. If that cast fails, then you really want a cast excpetion and not a null exception, since the cast tells you a lot more information about the problem.

The other bad thing I did was before I learned about the “as” operator. I did this a lot:

if (x is Converter) ((Converter)x).DoConversion();

This doesn’t throw an exception, but it does do two casts. Casts are not as expensive in .net as they are in many other languages, but they are still non-trivial, so you want to avoid unneeded casts.

Stefan Rusek | Perfectly cooking dry pasta

Perfectly cooking dry pasta

October 19, 2008 @ 12:35 pm

Stages of pasta

Most directions for cooking pasta say something like this: 1. Bring water to a boil, 2. Add a pinch of salt, 3. Let it boil for 8-10 minutes. Occasionally, the directions might mention something about altitude and longer cooking times. These directions will generally get you from the point where pasta is dry and hard to the point where your pasta is no longer hard or dry, but it won’t get you perfect pasta. The directions below will get you perfect pasta anywhere in the world at any altitude with any water.

This is my quick guide to making perfect pasta every time.

  1. Bring water to a boil.
  2. Add salt*, you want to get the water to the point where it is just about the taste of sea water, generally around 2 tablespoons.
  3. Add the pasta and use the the technique below to determine when the pasta is done.
  4. Drain and add your sauce.

Don’t add any oil. Pasta that is over cooked tends to stick together much more than pasta that is cooked right. Your sauce will stick to your pasta better without oil.

Knowing when your pasta is done.

Pasta uncookedPasta cooked for 5 minutesPasta fully cooked

(click to see huge versions)

Dry pasta starts out hard and smaller than the final product. As it cooks, the pasta absorbs water, expands, and slightly changes color. The color change is the secret perfect pasta. At about 5 minutes take a piece of pasta out of the pot and bite it in half. The dry parts in the center look whitish. Check the pasta every couple minutes or so until the white has completely disappeared. As it disappears you want to check it a little more often. Once the white is just about gone, but not completely (see the picture above) you want to let the pasta boil for another 15 seconds. This is about how long it is going to take you to get out your strainer plus a few seconds. It is imperative that you strain your pasta as soon as possible.Your pasta is done! This means that if you are not quick you probably want to skip the 15 second wait. You must to serve it immediately. If you cannot serve it within 3 minutes, you probably want to leave it a little underdone.

* Many people think that you add salt to the water when cooking pasta in order to raise the boiling point of the water and make the water cook faster. The amount of salt needed to raise the boiling point of water enough to make to make a difference will also make your pasta taste awful. The real reason to add salt to the water is to provide some flavor to the pasta, since dry pasta has no salt in it. In fact back before we polluted the ocean so much, Italians who lived by the sea would use water straight from the sea to cook pasta.