All good answers.
I would refine the "measure" part of the advice. I perform measurement for the purpose of quantifying any improvements I might make. However, for finding what needs to be fixed (and that is a different purpose), I get several samples of the call stack, manually.
Suppose, for simplicity, the program takes 20 giga-cycles to run, when it should take 10.
If I pause it 10 times at random, then in 5 of those occasions, more or less, it will be in one of those unnecessary cycles. I can see if the cycle is necessary by looking at each layer of the call stack. If any call instruction at any level of the stack could be eliminated, then the cycle is unnecessary. If such an instruction appears on multiple stacks, eliminating it will speed up the program, by an amount which is approximately the percentage of stack samples it is on.
Any instruction that shows up on multiple stacks is suspect - the more stacks, the more suspect. Now, call _main
is probably not one I can remove, but
foo.cpp:96 call std::vector::iterator:++
if it shows up on multiple stacks, is definitely a focus of attention.
One may, for style reasons, not want to replace it, but one will know roughly what price in performance is being paid for that choice.
So optimizing consists of identifying suspects and finding a way to replace or eliminate them.
The hard part (and I've done this many times) is understanding what is necessary and what is not. For that, you're going to absorb an understanding of how and why things are done in that program, so if some activity is a cycle-hog, you can know how to safely replace it.
Some cycle-hogs may be simple to fix, but you will quickly run up against ones that you don't know how to safely replace. For that, you need to be more familiar with the code.
It will help if you can pick the brain of someone who's already worked on the program.
Otherwise (assuming the code is ~ 10^6 lines, like I've worked on) you can get some speedup fairly easily, but to go beyond that, it can take months to get to where you're comfortable making significant changes.