You have just released a update of your product. It includes more or less nothing, just a minor bug fix and cleaner code. Tomorrow it will reached 10 million smartphone users. The next day your phone is calling, one hour before it normally wakes you up. Its your boss!
I recently read a blog post by Erik Dietrich about legacy code (http://www.daedtech.com/intro-to-unit-testing-5-invading-legacy-code-in-the-name-of-testability) and how refactoring can help you to make it testable. The articel (and it’s serie) is very vell written, and as he writes in a comment he aims for novices. With this post I want to change focus from correctnes to performance.
In several books and blogs you can read about clean code, reduce cymclomatic complexity, duplicate code and how refactoring can help you. And that works!
If its legacy code there will most of the time be a comment saying something that it shall be done with caution and you have to write unit tests before. Thats also great!
But what you don’t read (or very rare) is that you should profile the code before and after to spot any performance differences. Why? Consider this:
What do you think happens if you refactor a code snippet, that is used in one of your most CPU intense part?
It will take longer time!
A quick person will say that he will inline that code, either by function of through compiler flag.
Well...that sound good, but are you allowed to change a compiler flag?
And if it’s already there, do you know how large functions that will be inlined? Maybe a software architecture has decided he wants to have control of what is allowed to inline for several causes. It could be: controling final binary size, debugging issues or something else.
Jumping around takes time
What happens when you have refactored a code snippet, is making a jump to another place and do something there. This jump takes time. If you need to bring some parameters to this function, you have to store them in a register. And also the return adress. This takes time. If you need variables in the refactored function, you need to allocate memory for those. This takes time. And you have to jump back when you are finnished. And this takes time.
This itself isn’t a problem, but if it’s done milions of time in a part that is already highly loaded, it can be a problem.
A angry phone call
Even if you as a developer thinks the code looks cleaner and is easier to understand, you also need to understand the harware and your customer. Here is some senarios:
- There might be requirements about how long time a task can take.
- There might be limitation on how much of the cpu can be used before a wathdog generates an alarm, or in worst case reboots your system.
- There might be a customer starting asking questions why his system use more CPU load after your software update.
Learning to ride a bike is easy, the hard part is to ride in traffic jam