I've worked a lot with optimization in games/game engines (and for web apps), and the only way to stay sane and actually arrive at a performant product is to; a) never (or at least as little as possible) optimize beforehand and b) follow this simple workflow: profile, find out what the current bottleneck is (what's the thing that in the end is worst for the program), fix that and then start over again with the profiling. Performance problems are for some reason almost always super counter intuitive so we always have to measure before doing anything.

(I know, all that talk at uni about complexity and in the end it's a pretty useless "tool" for making real life high-performance applications :/ )