| In grad school I took a formal methods class where we proved properties about programs that completely changed how I think about bugs. The main things I took from the class were 1. Correctness of a program is distinct from its performance. 2. Program correctness can be proven. 3. Optimizing for performance often makes it harder to prove correctness. I do not actually use formal methods in my work as a developer, but the class helped improve my program quality nonetheless. Now I generally think in terms of a program being correct rather than having no bugs. Technically these are the same thing, but the change of language brings a change of focus. I generally try to use the term "error" instead of "bug", for an incorrect program. My strategy is to write the simplest correct version of the program first, convince myself that it is correct, and then optimize, if necessary without regressing on correctness. I generally use tests, rather than formal proofs, though, so of course there is still the possibility of uncaught errors, but this strategy works well overall. Thinking this way also gives me guidance as to how to break down a program into modules and subprograms: anything that is too big or complex for me to be able to reason about its correctness must be subdivided into pieces with well-defined correctness. It also has clarified for me what premature optimization means: it is optimizing a program before you know it's correct. (EDIT: fixed "reason about its complexity" to say "reason about its correctness" in the penultimate paragraph.) |
One obvious exception is code processing secret data. There, performance variance creates observable side-effects (timing side channels) which can be used to determine the secrets' values.
Another is any sort of hard real-time system, where performance is critical to correctness. For example, a brake-by-wire system that took 10 seconds to respond to the pedal being pressed would be incorrect, because of poor performance.
Otherwise, I agree. There might be some other exceptions, but striving for correctness first is a good way to write code.