Friday, June 27, 2008

Loop optimization trickery

A while ago I was playing around with C# 3.5 lambda expressions trying to work out how it behaves with variable scope.

What do you think is written to the console?
class Program
{
static void Main(string[] args)
{
// Write number to console in worker thread
for (int i = 1; i < 9; i++)
DoLater(() => Console.Write(i));
}

// Call action delegate on separate thread
static void DoLater(Action action)
{
// I'm avoiding using another lambda here to simplify test
new Thread(new ParameterizedThreadStart(DoLater)).Start(action);
}

// Calls the action after waiting for a second
static void DoLater(object action)
{
Thread.Sleep(1000);
((Action)action)();
}
}

If you initially guessed (like me) that it displays the numbers 1-9 in some random order (eg. '14385726') - you'd be wrong...   it actually produces '999999999' every time.

So I cranked up .net reflector (I love it) and had a look at my code (optimization set to .NET 1.0 - then translated by me):
private static void Main(string[] args)
{
AutoDelegateClass tmpVar = new AutoDelegateClass();
tmpVar.i = 1;
while (tmpVar.i < 9)
{
DoLater(new Action(tmpVar.Method));
tmpVar.i++;
}
}

This is much more obvious...  .net optimizes the lambda expression out of the loop!

Well that was unexpected, but guess what happens when I change main to this:
static void Main(string[] args)
{
for (int i = 1; i < 9; i++)
{
int j = i;
DoLater(() => Console.Write(j));
}
}

This works! ie. it does not optimize the lambda expression out of the loop.


Although confusing at first, it actually makes a lot of sense from the compiler point of view - the initial expression doesn't actually change, since we are referencing a mutable variable... so why not optimize it?

It might be convenient to turn off this optimization programmatically - kind of like a volatile keyword or something, but it's no big deal.

I guess it goes to show that functional code works best with immutable data... and that reflector is way cool.


BTW: The exact same thing occurs in foreach over a collection; and also using classes rather than structs.

Monday, June 23, 2008

UI - You don't know how much you suck

I made a small mistake in my last post - instead of 'do what you want' what I meant to say was:

Hire a damn graphic designer and buy some icons!

This is a subtle difference, but the delusion of competency is unfortunately common.m-diy-disaster

Like your home handyman disasters, the DYI attitude for user interfaces can cost you big time.

However IT departments are usually too cheap, and some developer ego's are too big to realize that they can't do everything... thus UI abominations are created everyday.


UI development is hard, harder than most people think. 

The UI layer is where everything comes together, and as a result it's here you find all the issues with the underlying architecture.


If you're a UI developer - you suck, so make sure you check out the UI guidelines for your dev system (Microsoft, Apple, Gnome or KDE).

If you're not a UI developer; shut up, fix your code and give the UI guys a break.

Oh, and good luck!

Disclaimer: I've done both jobs, so I suck twice as much.