Optimize … hold your horse!!

This story is from a meeting. There’s an issue with transaction creation code which the transaction contains multiple trade entries. Each trade entry need a matching electronic transfer instruction. My team mate found that the instruction that match the first trade is applied to every trade entries.

The code in question is something like this, in simplified Java.

BankTransferInstruction instruction = null;
for(TradeEntry entry : transaction.getEntries()) {
  if(instruction == null) {
    instruction = findBankTransferInstruction(entry);
  }
  entry.setBankTransferInstruction(instruction);
}

Did you see the problem? Take some time if you didn’t.

Actually this kind of problem is quite easy to solve. Something like :-

for (TradeEntry entry : transaction.getEntries()) {
  BankTransferInstruction instruction = findBankTransferInstruction(transaction);
  entry.setBankTransferInstruction(instruction);
}

As you can see, the problematic code looks for the instruction only once (when the variable is not null), and we resolve it by make it look for an appropriate instruction for every trade entry.

So in the meeting, someone say ‘why don’t we optimize it a little further ?’.

BankTransferInstruction instruction = null;
for(TradeEntry entry : transaction.getEntries()) {
  if(instruction == null ||
     (instruction != null && !instruction.isApplicable(entry)) {
    instruction = findBankTransferInstruction(transaction);
  }
  entry.setBankTransferInstruction(instruction);
}

We add one more condition so if the current instruction is applicable for the current entry, then it’s applied right away. This is probably faster than the previous one.

But, do we really need it ?

Before jumping right in with optimization, the most important thing to do is to evaluate whether or not there’s a performance problem. If it is then yes we’d need it. However keep in mind that optimization can sometime bring complexities (like the code above), and complexities hurts everyone in the long run. It means you have more possible points of failure, it means more unit test is needed, more maintenance is needed, more time need to be spent on this problem. It translate in to cost both directly and indirectly.

If you do optimization prematurely, it’ll become against you shortly after.

So before applying optimization, we should profile the code to see if the new code is actually the bottleneck, and how bad it performs. It’s not to late to apply optimization after we see the problem.