Marcin Wichary, Posted to Creative Commons Jan 05, 2006When a new company is formed, it's usually just the owner, possibly some partners, and a small staff. As they figure out how the business is to be run, they come up with their own ways of doing things. Over time, the staff grows, and more rules are created about how this or that is to be done. Eventually, it reaches critical mass, and all of these rules get quantified into written guidelines. Sometimes this can be a good thing. For example, coding style guidelines, if done correctly, can be a good thing.

Unfortunately, beyond a certain point, the company becomes bureaucratic, and the folks making the rules tend to be insulated from the bigger picture. People start clarifying rules to add finer grained detail. To the point of lunacy. You get stuff like instructions on whether of not to put a space before a semicolon; in which corner of the page a staple should be used, and at what angle it should be to the page, or how many sheets of TP to use for #1 vs. #2, and whether you should choose one ply or two ply. The rules start to resemble a mindless automaton, blindly forging ahead, without thought, sensibility or sentience. It's enough to suck the life out of any well-meaning effort.

Sadly, you also tend to get people whose sole purpose is to ensure that everyone complies with the rules. Whether or not they make sense. Regardless of context. Common sense and rational thought have no place in the process. Resistance is futile.

However, a resourceful engineer can always turn it around, use the rules to his advantage, and defeat the machine!

Derek K's company was a small branch of a much larger company. His team was in charge of processing and shipping whatever was sold each day. Most of the staff used a custom application to assist in this endeavour. It had originally been written in a language Derek had never heard of, was error prone and required manual fixes to the data before it could be run. While the program itself only took around five minutes to run, those manual fixes ended up wasting about a half an hour of everyone’s morning.

The larger company announced plans to create a new version of the program; one that would eliminate all the manual data fixes. Derek's team members cheered and waited with bated breath. Just two months after the announcement, the new software was delivered, and it actually had the promised feature: manual fixing of data was no longer required! But there was a new problem. It took over an hour to run.

After the program finished reconciliation, they found mistakes in the data that needed to be manually corrected and the program needed to be run again (so much for progress). With the old program, two or three cycles of fixing the data and rerunning the program were usually required, taking about an hour in total. With the new program, running it two or three times meant two or three hours. Everything these staff members did was dependent on getting the data ready to use. Losing that much time meant people were working overtime to get orders out, and some of them were going out late enough to miss the shipping deadlines. Late shipments meant unhappy customers.

Complaints were sent out, but the crack engineering squad from the larger office sent a global message stating that they had investigated the code, that “there was a lot going on under the hood” and they would be unable to improve the speed. A request to go back to the old program was denied, as “the data conversion was permanent.” Derek decided to take a look at the code.

After spelunking through the depths of the program, he found a for-each loop going through a collection to look for a matching item. Derek noticed that there was no exit for a match, so he added a break to the loop. After running a test, the program was running in half the time! Derek shrugged this off as a simple oversight and committed the change with a comment about the time save.

He’d just saved at least an hour for most people, if not more. Derek then began to dig further into the code, but before getting anywhere significant, an email hit his box: “Breaks from a loop is poor practice and is not allowed in any code. Please see 'Coding Practices' document, 'Loops' on page 23, part 3, paragraph 4.” Dumbfounded, Derek checked the codebase, and sure enough his change had been reverted. He shrugged off the ridiculousness of it, ripped out the for-each loop, replaced it with a while-loop, and checked that in instead, with a similar time improvement, again commenting about the time save.

Just a few minutes later, another email arrived: “While loops are not as efficient as the for..each loop, and should be avoided whenever there is an opportunity to use a for..each loop. Please see 'Coding Practices' document, 'Loops' on page 23, part 2, paragraph 2. PLEASE READ THE CODING PRACTICES DOCUMENTATION.”

Derek decided a walk would be a good idea before checking to confirm that his code had been reverted yet again. Not knowing what else to do, he decided to investigate the code further. Eventually, he figured out that the original loop was being run more than once – it was using a loop to search through a list of about 150,000 items - and it was being called around 20,000 times.

Derek converted the list into a hash map, completely blew away the loop, and tested the changes. The entire program now ran in about a minute. He checked in the changes, making sure to put in the comments: “Make sure to use the right kind of collection. Please see 'Coding Practices' document, 'Collections' on page 42, part 4, paragraph 1.”

That piece of code was never reverted.