Refactoring considered harmful, sometimes

Refactoring covers a broad swath of techniques to make code cleaner, more reliable, more maintainable, ... But sometimes, these attributes fight against each other. The usual attribute that causes trouble is "more performance". For example, consider factoring out a loop-invarient boolean:
for(....) {
    ...
    if(b) A;
    else B;
    ....
}
when b is loop-invarient, this can become:
if(b)
    for(...) {
        ...
        A;
        ...
    } else
    for(...) {
        ...
        B;
        ...
    }
Depending on a wide variety of factors, this can be faster. Although it might be slower. Careful benchmarking is required :-)

It is certainly less maintainable and less clear. When you see a pice of code that is the result of such a transformation, it's often difficult to tell that the two loops are related. If a bug is found in any of the replicated pieces of code, it has to be fixed in *both* places. Testing gets more complicated because the replicated code paths have to be independently (and somewhat redundantly) tested. To compound the problem, if you have (for example) multiple loop-invarient booleans, the code expansion is exponential (!!) in the number of factored-out booleans. This can get pretty insane pretty fast. I've seen instances where folks have tried to be clean about these transformations by clever use of C macros, but this can get really messy. And the code explosion can be dramatic: I got pulled into this problem years ago when someone checked a new line-drawing routine into the SunOS kernel (that's what Solaris was called before the SVr4 merge) that was bigger than the whole rest of the kernel. But it was fast. I got the job of fixing it :-(

For most people, this class of transformations should be avoided like the plague they are. But for folks like me who all too often need to do intense tuning, they are necessary. Can they be made cleaner? It's a pity that refactoring is viewed purely as something done in an IDE. Sometimes, you can do cool things if the refactoring is expressed in the language. But that's another blog entry.


PS. It's "build season" for the FIRST Robotics Competition. A couple of years ago Sun worked with FIRST to put a JavaVM on the industrial automation controller that they use. Before this, programming the robots was almost impossible. The contest turned into all-mechanical projects, with very little software. With the JVM (and the ability to debug running robots) they've become much easier to program. This year I'm mentoring the team at my younger daughter's school. I'm having a great time helping these kids write control software that works with a pile of motors and sensors. Can't wait to see it all work.
PPS. The RSA conference is in town, which was fun to wander through. It's hard to believe that so many companies making firewalls can succeed. The hard part for me is that I've become something of a magnet for former sun customers and partners to tell their tales of the shenanigans that the Oracle sales force engages in to trap customers. One got caught in a weird shell game where the oracle team was working hard chasing him around town to prevent him from talking to another vendor - physically interposing themselves between the vendor and the customer. As frustrating and pathetic as the stories are, I find them easy to manage by treating them as humor. It is outrageously goofy the stunts that get pulled (although the 5x to 20x price increases often forced on customers are infuriating - talk to anyone "upgrading" from Sun Identity Manager).
February 18, 2011