18.2.08

Iteration with Lambda Expressions

I started using lambda expressions recently, and converted all my anonymous delegates. I like the syntax for a lot of things, but not all. Basically, any simple, one or two line predicates or actions are very neatly rewritten into a lambda expression.

But then we hit the question of performance. Delegates and lambda expressions are exactly the same thing in C#. The transformation between the two is ridiculously trivial, so it's not surprising that they are compiled into the same IL.

delegate(int i)
{
DoWork(i);
}
i => DoWork(i)


But let's talk about real-world applications and their performance implications. Let's say I have an array, and I want to iterate through it and call some method with each element. Thanks to C#'s wonderful language constructs, I can think of several ways to accomplish this:

for (int i = 0; i <>
foreach (int i in Program.array)
{
Program.DoWork(i);
}
Array.ForEach(Program.array,
delegate(int i)
{
Program.DoWork(i);
}
);
Array.ForEach(Program.array, x => DoWork(x));

As I already mentioned, the last two are functionally equivalent, but I'll include both just for demonstration and completeness. Here's results for an array of 100,000,000 integers.







MethodTime
for loop0.6318259s
foreach0.9067668s
Array.Foreach (delegate)1.284918s
Array.Foreach (lambda)1.2216206s


As you can see, a simple for loop is the fastest. Foreach is more efficient over arrays than over collections--it does actually use indexing to go through the array rather than an enumerator. Array.Foreach takes twice as long. Most of the slow-down is that it's doing a delegate call.

In conclusion, nothing beats a good ol' for loop. On the other hand, the simplicity and clarity of lambda expressions is similar to what foreach brought us. Foreach always ran slower than a for loop, but removed the need to manage indexes, create a temp variable, etc. I would argue that it reduces errors and makes the code more readable. In a way, lambda expressions are just a continuation of the same.

No comments: