<<< Measuring Infinity


Wednesday, November 12, 2003 10:06 PM >>>

The Little Boy Explains

Wednesday,  11/12/03  05:18 PM

The other day I posted The Emperor's New Code, a heretical critique of "Longhorn" Microsoft's upcoming version of Windows.  I expected to get a lot of links, and I did - thanks Dave, Tim, and Robert! - and I expected to get a lot of criticism, and I did.  I am like the little boy who cried "the emperor's not wearing any clothes", and of course some noblemen cannot admit this; it would be too embarrassing.  Or maybe the little boy just can't see the clothes :)  So.  Dialog is always healthy, right!

I have to admit, I took a somewhat extreme position in the interest of making my point.  In real life I don't feel as strongly negative about Longhorn.

But I do feel strongly about my central point: The most important thing is not how easy it is to build code, the most important thing is how well the code runs once it is built.  As a professional developer, you simply have to believe this, or your customers will suffer (as will your business).

I'd like to take a moment to discuss the most prevalent reactions.

  • "Premature optimization is the root of all evil".

Ha ha, cute.  But I'm not talking about optimization in my article.  I'm talking about efficient design.  If you think these two things are the same, I may not be able to help you.  Application performance is determined by four things, in this order:

  • Network utilitization.
  • Disk utilitzation.
  • Memory utilization.
  • CPU utilitization.

They are in this order because of their relative speed; networks are really slow compared to disks, which are really slow compared to memory, which is slow compared to CPUs.  There are very few applications which are actually CPU-bound.  Most of the time an application's performance is determined by disk and network access.  Optimizing this requires good design.  It isn't something you add in later by setting a compiler switch or refactoring a subroutine.  Sorry.

Oh, and if you use memory inefficiently you end up paging, which causes CPU-bound operations to become disk-bound.  That's why memory usage impacts performance.  (And why Windows' poor paging is such an issue.)

  • "There are, too, 'important apps' being written in .NET."

Oh yeah, name them.  Everyone who said this failed to name them.  I wrote: "Feel free to indulge yourself by making a list of counter-examples.  It will be a short list."  So far it is a null list.

Hey, I realize there are a lot of useful programs written as managed code.  My favorite RSS aggregator, SharpReader, is written in .NET, and I use it every day.  But is it an "important app" in the sense of Microsoft Word or Adobe Photoshop?  No.  Is it expensive commercial code?  No.  It is a cool freeware app written by one guy.

I have good friends at a [not-to-be-named] company which builds financial transaction systems.  The core system is client/server; VB/C++ under Windows on the clients, C++ under Unix on the servers.  Over many years it has evolved into a solid, high-performance product.  They recently recoded a major subsystem in .NET, and it has been a disaster.  The new subsystem is really slow, the thin-client GUI is horrible, and their customers are up in arms.  The programmers do love C#, but so what?

I know, one data point doesn't prove anything.  So, your serve.

  • "As long as an application is fast enough, it doesn't have to be faster."

I readily admit not all applications are performance critical.  And I accept that speed is not the only measure of performance; usability, functionality, and robustness are all important.  You have to optimize for the right things to make customers happy.

I'm probably a little three-sigma in that I've spent my whole professional life building systems which were performance critical.  Financial transaction systems, large websites, busy websites, and systems which manage large images.  At no time did we reach a point where we were "fast enough"; there was always more load to handle, more hardware to avoid buying.  And speed was always a competitive weapon.  Maybe not everyone feels the need for speed.  But I do.

  • "The most important thing is how easy it is to build code that runs well."

I agree with this, but only because the most important thing is how well the code runs once it is built.  (Yeah, I'm in a loop.)  I'm all for things which make it easy to build good code.  And I'm all for things which improve programmer productivity.  To the extent that Longhorn's technology helps build good code and improve productivity, it is good.  But.  I don't think hiding stuff under layers of abstraction always makes it easier to build good code.  Sometimes, it makes it harder.

{ Ask yourself, what is easier to optimize, the hwnd API or MFC?  Aha.  What is easier to optimize, sockets or the Internet Transfer control.  Aha. }

Many people may disagree with me on this, so be it.  I'm totally from Missouri on this issue.

In between the time I posted my article and today, I spent much of my time optimizing Aperio's ImageServer product.  This program acts as a simple HTTP server, fielding rich-client and web requests for image data from a store of very large virtual microscopy images.  It currently runs at around 550 requests/second on a reasonably powerful PC, pumping out 6.5MB/s of image data on a 100Mb LAN.  It is written in C++ and uses sockets.  As I was working on this code, I was trying to imagine writing this application in Java or C#, and I just couldn't do it.  Maybe someday, but not today.

You might say, sure, but at least you didn't write it in assembly language!  And that's true.  With modern processors the code generated by compilers is better than what I could generate by hand - otherwise I might be tempted :)  And as I mentioned above, the order of priority here is 1) optimize network, 2) optimize disk, 3) optimize memory, 4) optimize CPU.  So getting the network and disk access right is what really matters.  And getting the caching right.  

Just like it does in an OS... 

  • "Longhorn is not really reinventing the wheel."

Oh really?  Check out Jon Udell's thoughts on this, or Tim Bray's, they put it better than I could.  I think the general reaction people are having to Longhorn is "wow, this is really different".  Maybe that's good, but change for the sake of change?  As Jon wrote, "If the suite of standards now targeted for elimination from Microsoft's actively-developed portfolio were a technological dead end, ripe for disruption, then we should all thank Microsoft for pulling the trigger.  If, on the other hand, these standards are fundamentally sound, then it's a time for what Clayton Christensen calls sustaining rather than disruptive advances.  I believe the ecosystem needs sustaining more than disruption."  Amen.

To add to the long list of examples, consider Monad, Microsoft's new command-line shell.  Hey, it looks cool.  But why not use ksh?

  • "Mozilla is faster than IE, so obviously XUL doesn't hurt."

I have a 2GHz Compaq laptop, running XP Pro.  Modern equipment, I think you would agree.  When I launch IE it takes about 2s before I have a window.  Launching Mozilla takes about 6s.  Try counting to 6 right now to see how slow this is.

XUL is used for the Mozilla GUI, not for page layout.  The overhead of XUL is manifested in that startup time.  The speed of loading and rendering a page is not affected by XUL; it may be that Mozilla is faster at loading or rendering pages (I actually don't think so), but even if it is that has nothing to do with XUL.

  • "All PCs will have GPUs by the time Longhorn comes out, so vector graphics will be fast."

I accept this.  And I like vector graphics, I went out of my way to say so.  This is the one thing that stands out as a positive user benefit in Longhorn.

{ BTW, Apple's OS X uses a GPU for GUI rendering ["Quartz"], and it works great. }

  • "WinFS is, too, going to be fast."

We'll see.  Right now in the pre-beta build ("PDC bits") it is tectonic.  I think using metadata for some files might make sense, but adding it in as a general layer between applications and NTFS does not.

Scott Loftesness put it well: "Microsoft has never invested in performance - they've always relied on hardware vendors saving their bacon with more memory, faster processors, etc...  Where this strategy is most likely to fail with Longhorn is in the file system where the magnitude of disk I/O performance improvements are relatively miniscule compared to the rest of the system components."  Maybe they'll end up shipping Longhorn without WinFS, or with a stripped down WinFS, or make it so WinFS is only used for certain files.  It is really early days, yet.

I wrote: "I'm guessing it is painfully slow now and that there’s a bunch of people working hard trying desperately to make it fast enough."  Scoble replied: "WinFS is currently undergoing a major rework for the next few months just to get its performance up."  I knew it.  So - time will tell...

My colleague Allen summed up the whole thing very succinctly; "more abstraction always means less efficiency".  Exactly.

I want to end this rant on a positive note.  Scoble noted "I asked you all to hate Longhorn and Ole is just following directions.  I'm actually happy to see the feedback!"  Robert has a great attitude, and I appreciate that Microsoft appears to be listening.  I don't hate Longhorn at all (really there are very few things I hate).  I am trying to use my puny little pulpit to ever-so-slightly steer the gigantic Microsoft ship gently toward improving application performance.  I respect Microsoft tremendously for sharing the guts of Longhorn so early, and for genuinely trying to assimilate feedback.

This is your friendly neighboorhood curmugeon, signing off...


(click for fullsize diagram)

P.S. Oh, by the way, here's a diagram of Longhorn.  It's beautiful!  And I'm sure you'll find it as easy to comprehend as I did.