Thursday, September 28, 2006

Refactoring away performance

Donald Knuth once said that "Premature optimization is the root of all evil (or at least most of it) in programming", something that the agile community advocates, and I myself agree with (for the most part).

The idea is that writing very fast tight code that performs amazingly well, but lacks readability, might be a waste of time. You might not need that amazing performance, or it could be that no matter how fast your code is the web service provider that it subscribes to or the database serving records is so slow that it doesn't really matter anyway. No, instead write readable, well designed and maintainable code. If you need to get more performance later then profile your software, find the slow bits and optimise them. After all, it's easier to optimise well structured easy to read code anyway.

This is all well and good, and most of the time is the right way to go. But I'm a little concerned that we might be building unnecessarily slow software. Take for example the refactoring technique "Replace temp with query". Replace temp with query states that this code:

string desc = MyObject.GetDescription ();

this.Text = desc;
AFileClass.SaveFile (desc);
AnoherClass.Description = desc;


should be replaced with:

this.Text = MyObject.GetDescription ();
AFileClass.SaveFile (MyObject.GetDescription ());
AnoherClass.Description = MyObject.GetDescription ();


So that rather than getting the description and storing it in a temporary variable we re-query the MyObject class each time.

This refactoring (as with some others) decreases performance and adds nothing to code readability. What is the cost to our application of a multitude of small performance degrading refactorings? Would we notice the drop in performance in our short code-deliver-test cycles? Or would we end up at the end of development with an application that just feels a bit sluggish?

If we did end up with an app that needed a performance boost it would be a long painful process to go through the code and remove all these small refactorings.

Refactoring: Improving the Design of Existing Code

Martin Fowler's discussion book and catalogue of common refactorings is a hugely interesting read. It presents the reader with an overview of what refactoring is, how it evolved, and why we should be making use of the technique in software development.

Refactoring is the process of improving software by making it more readable, maintainable, and shaping it into a better design. Many people consider the end point of a successful refactor to be a design pattern (Refactoring to Patterns).

The bulk of this book is given over to a catalogue of possible refactorings. Some very simple, such as Encapsulate field (i.e. replace a public field with a private field and a public property), to other more complicated efactorings such as Introduce Null Object.

A large part of refactoring is being able to test that your changes have not broken existing code. For that reason this book advocates and discusses automated unit testing as a way to verify that your refactorings haven't broken anything.

This book is getting on a bit now, but there are still a large number of software professionals who have not embraced a more agile way of working who would benefit from the gentle introduction that this book delivers.

Another point to make is that this book is Java based, but that should not put of any C# professional from reading it.

Effective C#

I found this book difficult to read, not because it was technically over heavy, but because the style didn't seem to let me really get into it. I've not been able to pin down exactly what it was about the style; maybe it was too bullet-point like and lacked depth.

Style aside this is a very good book, especially for anyone who is migrating from C/C++ to C#. In fact I'd say this book is essential if you are coming to C# from a C/C++ background. I wish I'd read this book when I first started programming in C#.

The book covers C# language, .Net mechanics, and even touches on some design issues. I found that I wanted more depth from the book, especially on some of the chapters about design. To be fair to the author he does say that he is not attempting to write a book about design, and that such topics are best dealt with by entire books rather than a few chapters, but I think a little more detail and discussion would have added to the book.

Unfortunately this book only covers .Net 1.1. I've been unable to find any news about a .Net 2.0 revision.